P4116 Qtree3
思路
可以树剖可以LCT,树剖就是每个重链开一个SET维护一下黑点的深度
非常不优美
使用LCT,在splay上二分找出需要的节点即可
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
struct Node{
int son[2],sum,inv,fa,val;
}SPT[100100];
int n,q;
bool isrl(int o){
return SPT[SPT[o].fa].son[1]==o;
}
bool isroot(int o){
return SPT[SPT[o].fa].son[0]!=o&&SPT[SPT[o].fa].son[1]!=o;
}
void pushup(int o){
SPT[o].sum=SPT[SPT[o].son[0]].sum+SPT[o].val+SPT[SPT[o].son[1]].sum;
}
void pushdown(int o){
if(SPT[o].inv){
SPT[SPT[o].son[0]].inv^=1;
SPT[SPT[o].son[1]].inv^=1;
swap(SPT[o].son[0],SPT[o].son[1]);
SPT[o].inv^=1;
}
}
void rorate(int o){
if(isroot(o))
return;
int f=SPT[o].fa;
int g=SPT[f].fa;
pushdown(f);
pushdown(o);
int which=isrl(o);
if(!isroot(f))
SPT[g].son[SPT[g].son[1]==f]=o;
SPT[o].fa=g;
SPT[f].son[which]=SPT[o].son[which^1];
SPT[SPT[o].son[which^1]].fa=f;
SPT[o].son[which^1]=f;
SPT[f].fa=o;
pushup(f);
pushup(o);
}
void allpush(int o){
if(!isroot(o))
allpush(SPT[o].fa);
pushdown(o);
}
void splay(int o){
allpush(o);
for(int f;!isroot(o);rorate(o)){
if(!isroot(f=SPT[o].fa))
rorate((isrl(f)==isrl(o))?f:o);
}
}
void access(int o){
for(int y=0;o;o=SPT[y=o].fa)
splay(o),SPT[o].son[1]=y,pushup(o);
}
void makeroot(int o){
access(o);
splay(o);
SPT[o].inv^=1;
pushdown(o);
}
int findroot(int o){
access(o);
splay(o);
pushdown(o);
while(SPT[o].son[0])
pushdown(o=SPT[o].son[0]);
return o;
}
void link(int x,int y){
makeroot(x);
if(findroot(y)!=x)
SPT[x].fa=y;
}
int dfs(int x){
if(SPT[x].val){
if(SPT[SPT[x].son[0]].sum)
return dfs(SPT[x].son[0]);
else
return x;
}
else{
if(SPT[SPT[x].son[0]].sum)
return dfs(SPT[x].son[0]);
else if(SPT[SPT[x].son[1]].sum)
return dfs(SPT[x].son[1]);
}
}
int query(int x){
access(x);
splay(x);
pushdown(x);
if(!(SPT[SPT[x].son[0]].sum+SPT[x].val))
return -1;
if(SPT[x].val&&(!SPT[SPT[x].son[0]].sum))
return x;
return dfs(SPT[x].son[0]);
}
int main(){
scanf("%d %d",&n,&q);
for(int i=1;i<n;i++){
int a,b;
scanf("%d %d",&a,&b);
link(a,b);
}
makeroot(1);
for(int i=1;i<=q;i++){
int opt,x;
scanf("%d %d",&opt,&x);
if(opt==0){
splay(x);
SPT[x].val^=1;
// pushup(x);
}
else{
printf("%d\n",query(x));
}
}
return 0;
}