题意:询问与 u u 相同颜色的联通块的大小,带修改
考虑建立黑白两颗,答案就是在相应 lct l c t 中, u u 所属的那棵树的大小了
至于修改的话一个非常暴力的想法就是直接然后 link l i n k
这样的话碰到菊花图就 GG G G 了(下面我们讨论维护黑树的 lct l c t ,白树同理)
考虑到原树的形态是不会变的,所以我们可以设在 lct l c t 中如果有边 edge(u,v) e d g e ( u , v ) ,那么 v v 就是黑色(不一定是黑色)
这样的话我们 cut c u t 和 link l i n k 都只要管 edge(u e d g e ( u 原树中的父亲, u) u ) 这条边了
统计答案的话就把它 access a c c e s s 上去后然后判断这条链最上面的那个点是不是黑点,不是就要输出最上面那个点的儿子节点
要是不会 lct l c t 维护子树信息可以先做做这个题目
然后这题因为只要 link,cut l i n k , c u t egde(fa[u],u) e g d e ( f a [ u ] , u ) 这条边所以写法可以特殊一点
具体怎么特殊看代码
#include<bits/stdc++.h>
#define fp(i,a,b) for(int i=a,I=b;i<=I;++i)
#define go(i,u) for(int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sd(T&x){
char c;T y=1;while(c=gc(),(c<48||57<c)&&c!=-1)if(c==45)y=-1;x=c^48;
while(c=gc(),47<c&&c<58)x=(x<<1)+(x<<3)+(c^48);x*=y;
}
char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
template<class T>inline void we(T x){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e5+5;
typedef int arr[N];
struct eg{int nx,to;}e[N<<1];
int n,m,ce;arr fi,fa,sz,col;
struct LCT{
int Col,ch[N][2];arr fa,sz,tp;
#define lc(u)(ch[u][0])
#define rc(u)(ch[u][1])
inline void op(int u,int w){sz[u]+=w,tp[u]+=w;}
inline bool ir(int u){return lc(fa[u])^u&&rc(fa[u])^u;}
inline bool gf(int u){return rc(fa[u])==u;}
inline void up(int u){sz[u]=sz[lc(u)]+sz[rc(u)]+tp[u];}
inline void rot(int u){
int p=fa[u],k=gf(u);
if(!ir(p))ch[fa[p]][gf(p)]=u;
if(ch[u][!k])fa[ch[u][!k]]=p;
ch[p][k]=ch[u][!k],ch[u][!k]=p;
fa[u]=fa[p],fa[p]=u,up(p);
}
void splay(int u){
for(int f=fa[u];!ir(u);rot(u),f=fa[u])
if(!ir(f))rot(gf(u)==gf(f)?f:u);
up(u);
}
inline void acc(int u){for(int v=0;u;u=fa[v=u])splay(u),tp[u]+=sz[ch[u][1]]-sz[v],ch[u][1]=v,up(u);}
inline void brt(int u){acc(u),splay(u);}
inline void link(int u,int v){
if(!v)return;
brt(v),splay(u),tp[fa[u]=v]+=sz[u];
}
inline void cut(int u,int v){
if(!v)return;
brt(u),fa[lc(u)]=0,lc(u)=0,up(u);
}
inline int Gf(int u){brt(u);while(lc(u))u=lc(u);return u;}
inline int qry(int u){
int p=Gf(u);splay(p);
return col[p]==Col?sz[p]:sz[ch[p][1]];
}
}T[2];
inline void add(int u,int v){e[++ce]=eg{fi[u],v},fi[u]=ce;}
void dfs(int u){sz[u]=1;go(i,u)if(v!=fa[u])T[0].fa[v]=fa[v]=u,dfs(v),sz[u]+=sz[v];}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
sd(n),T[1].Col=1;int u,v;
fp(i,2,n)sd(u),sd(v),add(u,v),add(v,u);
dfs(1);sd(m);fp(i,1,n)T[0].tp[i]=T[0].sz[i]=sz[i];
while(m--){
sd(v),sd(u);int&c=col[u];
if(v)T[c].cut(u,fa[u]),T[c].op(u,-1),c^=1,T[c].op(u,1),T[c].link(u,fa[u]);
else we(T[c].qry(u));
}
return Ot(),0;
}