[HEOI2016/TJOI2016]树
[HEOI2016/TJOI2016]树
这是一道树剖板子题,所以我们没什么讲的
题解
我们用线段树维护树剖序上的\(sum\)值,即为染色的数量的\(sum\),当\(sum=0\)时,从\(x\)节点向上爬树,当我们查询到这条链的\(sum>=1\)时二分答案即可。
#include<bits/stdc++.h>
using namespace std;
const int MN=1e5+100;
int n,q;
int head[MN],cnt;
struct node{
int nxt,to;
}e[MN<<1];
inline void add(int a,int b){e[++cnt].nxt=head[a],head[a]=cnt,e[cnt].to=b;}
int son[MN],siz[MN],fa[MN],dep[MN];
void dfs1(int now,int pre){
dep[now]=dep[pre]+1,fa[now]=pre,siz[now]=1;
for(int i=head[now];i;i=e[i].nxt){
int to=e[i].to;
if(to==pre)continue;
dfs1(to,now);
siz[now]+=siz[to];
if(siz[to]>siz[son[now]])son[now]=to;
}
}
int dfn[MN],top[MN],tot,name[MN];
void dfs2(int now,int tp){
top[now]=tp,dfn[now]=++tot,name[tot]=now;
if(son[now])dfs2(son[now],tp);
for(int i=head[now];i;i=e[i].nxt){
int to=e[i].to;
if(to==fa[now]||to==son[now])continue;
dfs2(to,to);
}
}
#define lc id<<1
#define rc id<<1|1
struct tree{
int l,r,sum;
}t[MN<<2];
void pushup(int id){
t[id].sum=t[lc].sum+t[rc].sum;
}
void build(int id,int l,int r){
t[id].l=l,t[id].r=r;
if(l==r)return;
int mid=(l+r)>>1;
build(lc,l,mid),build(rc,mid+1,r);
}
void change(int id,int k){
if(t[id].l==t[id].r&&t[id].l==k){
t[id].sum=1;
return;
}
int mid=(t[id].l+t[id].r)>>1;
if(k<=mid)change(lc,k);
else change(rc,k);
pushup(id);
}
int get_sum(int id,int l,int r){
if(t[id].l>=l&&t[id].r<=r)return t[id].sum;
int mid=(t[id].l+t[id].r)>>1,ans=0;
if(l<=mid)ans+=get_sum(lc,l,r);
if(r>=mid+1)ans+=get_sum(rc,l,r);
return ans;
}
int lower(int l,int r){
if(l==r)return name[l];
int mid=(l+r)>>1;
if(get_sum(1,mid+1,r))return lower(mid+1,r);
else return lower(l,mid);
}
int query(int x){
int ans=0;
while(!ans){
int sum=0;
sum=get_sum(1,dfn[top[x]],dfn[x]);
if(sum){
ans=lower(dfn[top[x]],dfn[x]);
}
else x=fa[top[x]];
}
return ans;
}
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d%d",&n,&q);
for(int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs1(1,0);dfs2(1,1);build(1,1,n);change(1,dfn[1]);
int x;char s;
while(q--){
scanf("%s%d",&s,&x);
if(s=='Q')printf("%d\n",query(x));
else change(1,dfn[x]);
}
return 0;
}

浙公网安备 33010602011771号