专栏文章
题解:P5478 [BJOI2015] 骑士的旅行
P5478题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mip4b3km
- 此快照首次捕获于
- 2025/12/03 05:56 3 个月前
- 此快照最后确认于
- 2025/12/03 05:56 3 个月前
第三篇紫题题解!
分析
观察题目,发现单单从题目描述上来看十分难处理。应为有 个东西要维护。
但当观察数据范围 ,可以得知这道题上的突破点是 上面。
处理
考虑进行暴力维护,对于每一个线段树节点和答案使用
multiset,因为这个东西可以十分便捷的进行插入、排序、查询和删除操作。其余直接按照树链剖分暴力维护。细节
注意千万千万千万不能两个
multiset 中的元素直接 insert 进一个 multiset 中,再一个个弹出去。这样时间复杂度就劣化为近似 详见此贴。
code:(码风极丑,因为以为 TLE #1 是被卡常)
CPP#include<bits/stdc++.h>
using namespace std;
char *p1,*p2,buf[100009];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
inline unsigned int read(){
unsigned int x=0;
char ch=nc();
while(ch<48||ch>57){
ch=nc();
}
while(ch>=48&&ch<=57)
x=(x << 3) + (x << 1) +ch-48,ch=nc();
return x;
}
inline void out(unsigned int x) {
if(x>9)out(x/10);
putchar('0'+x%10);
}
#define N 40009
#define ls(i) (i<<1)
#define rs(i) ((i<<1)|1)
#define sp(i,j) i^=j,j^=i,i^=j
unsigned int n,m,q,k;
multiset<unsigned int> d[N];
vector<unsigned int> e[N];
unsigned int res, id[N], son[N], fa[N], h[N], top[N], sizee[N], rk[N], f[N], p[N];
struct V{
multiset<unsigned int> d;
unsigned int l, r;
inline V operator+(const V &a) const {
V c;
c.l = l, c.r = a.r;
int cnt = 0;
for(auto it: a.d) {
cnt++;
if(cnt <= k) c.d.insert(it);
else break;
}
cnt = 0;
for(auto it: d) {
cnt++;
if(cnt <= k) c.d.insert(it);
else break;
}
while(c.d.size() > k) c.d.erase(--c.d.end());
return c;
}
};
namespace xds{
V tree[(N << 2) + 1];
inline void build(const unsigned int &i, const unsigned int &l, const unsigned int &r) {
tree[i].l = l, tree[i].r = r;
if(l == r) {
return;
}
const unsigned int mid = (l + r) >> 1;
build(ls(i), l, mid),build(rs(i), mid + 1, r),tree[i] = tree[ls(i)] + tree[rs(i)];
}
inline void change(const unsigned int &i, const unsigned int &x) {
if(tree[i].l == tree[i].r) {
return;
}
const unsigned int mid = (tree[i].l + tree[i].r) >> 1;
if(x <= mid) change(ls(i), x);
else change(rs(i), x);
tree[i] = tree[ls(i)] + tree[rs(i)];
}
inline V ask(const unsigned int &i, const unsigned int &l, const unsigned int &r) {
if(l <= tree[i].l && tree[i].r <= r) return tree[i];
const unsigned int mid = (tree[i].l + tree[i].r) >> 1;
if(l <= mid && mid < r) return ask(ls(i), l, r) + ask(rs(i), l, r);
if(l <= mid) return ask(ls(i), l, r);
if(mid < r) return ask(rs(i), l, r);
}
}
inline void dfs(const unsigned int &u,const unsigned int &faa,const unsigned int &hh) {
h[u]=hh,fa[u]=faa,sizee[u]=1;
unsigned cnt=0;
for(auto to:e[u]) {
if(to==faa) continue;
dfs(to,u,hh+1);
sizee[u]+=sizee[to];
if(cnt <= sizee[to]) son[u]=to,cnt=sizee[to];
}
}
inline void dfs2(const unsigned int &u,const unsigned int &topp) {
top[u]=topp,id[u]=++res,rk[res]=u;
if(!son[u]) return;
dfs2(son[u],topp);
for(auto to:e[u]) {
if(to==fa[u]) continue;
if(to==son[u]) continue;
dfs2(to,to);
}
}
inline void ask(unsigned int &x, unsigned int &y) {
V ans;
while(top[x] ^ top[y]) {
if(h[top[x]] < h[top[y]]) sp(x, y);
ans = ans + xds::ask(1, id[top[x]], id[x]);
x = fa[top[x]];
}
if(id[x] > id[y]) sp(x, y);
ans = ans + xds::ask(1, id[x], id[y]);
if(!ans.d.size()) putchar('-'), putchar('1');
else {
for(auto it: ans.d)
out(-it), putchar(' ');
}
putchar('\n');
}
int ys[N];
inline void js(const unsigned int &i, const unsigned int &l, const unsigned int &r) {
if(l == r) {
ys[l] = i;
return;
}
const unsigned int mid = (l + r) >> 1;
js(ls(i), l, mid),js(rs(i), mid + 1, r);
}
int main(){
n = read();
for(unsigned int i = 1, _u, _v; i < n; ++i) _u = read(), _v = read(), e[_u].push_back(_v), e[_v].push_back(_u);
dfs(1, 0, 1), dfs2(1, 1);
js(1, 1, n);
m = read();
for(unsigned int i = 1; i <= m; ++i) {
f[i] = read(), p[i] = read(), xds::tree[ys[id[p[i]]]].d.insert(-f[i]);
}
q = read(), k = read(), xds::build(1, 1, n);
while(q--) {
unsigned int op, x, y;
op = read(), x = read(), y = read();
if(op == 1) ask(x, y);
if(op == 2) xds::tree[ys[id[p[x]]]].d.erase(xds::tree[ys[id[p[x]]]].d.find(-f[x])), xds::change(1, id[p[x]]), p[x] = y, xds::tree[ys[id[p[x]]]].d.insert(-f[x]), xds::change(1, id[p[x]]);
if(op == 3) xds::tree[ys[id[p[x]]]].d.erase(xds::tree[ys[id[p[x]]]].d.find(-f[x])), f[x] = y, xds::tree[ys[id[p[x]]]].d.insert(-f[x]), xds::change(1, id[p[x]]);
}
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...