FlashHu大佬太强啦%%%
首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权
先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点,然后不断地往上更新,如果更改之后父亲的儿子中权值为$1$的儿子个数大于权值为$0$的儿子个数,那么就继续更新父亲,直到不能更新为止
不难发现,我们每一个更改的都是树上的一条链。而且,只有当点权为$1$时,才能因为修改使点权变为$2$,使输出改变,从而更新祖先。那么,我们需要的就是对于每一个节点,从它向上的连续的点权为$1$的一部分
如果是从$1$变为$0$同理,我们要维护从每一个节点向上的连续的点权为$2$的一部分
那么我们对于每一个节点,先access,然后记录splay中最深的点权不为$1$和$2$的点,然后把它给splay到根,再对右子树进行区间修改,对他自己单点修改
然后注意特判,如果整棵splay里都没有点权不为$1$或$2$的点,那么直接区间修改
然后怎么记录点权嘞?我们先把所有叶子结点的值*2,那么只有0和2两种值,然后每一个节点只要加上它所有叶子结点的值/2就是这个点的点权了
1 //minamoto 2 #include3 #include 4 #include 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-'0'10 char ch;bool flag=0;int res;11 while(!isdigit(ch=getc()))12 (ch=='-')&&(flag=true);13 for(res=num;isdigit(ch=getc());res=res*10+num);14 (flag)&&(res=-res);15 #undef num16 return res;17 }18 char sr[1<<21];int C=-1;19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}20 inline void print(int x){21 sr[++C]=x|48,sr[++C]='\n';22 }23 const int N=500005,M=1500005;24 int fa[M],ch[N][2],n1[N],n2[N],tag[N],v[M];25 int d[N],q[M],h=1,t,ans;26 #define ls ch[x][0]27 #define rs ch[x][1]28 inline bool isrt(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}29 inline void pup(int x){30 //先右儿子再自己最后左儿子31 //因为&是短路运算符,有一个为假就会自动跳出 32 if(!(n1[x]=n1[rs])&&!(n1[x]=x*(v[x]!=1))) n1[x]=n1[ls];33 if(!(n2[x]=n2[rs])&&!(n2[x]=x*(v[x]!=2))) n2[x]=n2[ls];34 }35 inline void pdown(int x,int t){36 //被区间修改的要么都是1要么都是2,直接反转信息37 v[x]^=3,swap(n1[x],n2[x]),tag[x]+=t;38 }39 void all(int x){40 if(!isrt(x)) all(fa[x]);41 if(tag[x]) pdown(ls,tag[x]),pdown(rs,tag[x]),tag[x]=0;42 }43 void rotate(int x){44 int y=fa[x],z=fa[y],d=ch[y][1]==x;45 if(!isrt(y)) ch[z][ch[z][1]==y]=x;46 fa[x]=z,fa[y]=x,fa[ch[x][d^1]]=y,ch[y][d]=ch[x][d^1],ch[x][d^1]=y,pup(y);47 }48 void splay(int x){49 all(x);50 for(int y=fa[x],z=fa[y];!isrt(x);y=fa[x],z=fa[y]){51 if(!isrt(y))52 ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y);53 rotate(x);54 }55 pup(x);56 }57 inline void access(int x){58 for(int y=0;x;x=fa[y=x])59 splay(x),rs=y,pup(x);60 }61 int main(){62 // freopen("testdata.in","r",stdin);63 int n=read();64 for(int i=1;i<=n;++i)65 d[fa[read()]=fa[read()]=fa[read()]=i]=3;66 for(int i=n+1;i<=3*n+1;++i) v[q[++t]=i]=read()<<1;67 while(h<=t){68 int x=q[h++];if(x<=n) pup(x);69 v[fa[x]]+=v[x]>>1;70 if(!(--d[fa[x]])) q[++t]=fa[x];71 }72 ans=v[1]>>1;73 int q=read();74 while(q--){75 int x=read(),k=(v[x]^=2)-1;76 access(x=fa[x]),splay(x);77 if(~k?n1[x]:n2[x]){78 splay(x=(~k?n1[x]:n2[x]));79 pdown(rs,k),pup(rs);80 v[x]+=k,pup(x);81 }82 else pdown(x,k),pup(x),ans^=1;83 print(ans);84 }85 Ot();86 return 0;87 }