正题
难度虚高
想一想就会做了,直接用ans[0/1]来维护将0/1放进当前点的splay的末端得出来的信息,那些非节点的权值和轻儿子的权值用一个tot来维护,acs的时候直接更改,upd就看看将0/1放进右儿子会有什么答案,然后再算自己,在丢到左儿子.代码比其他LCT的都短,因为不用换根,就少了dfs下放标记和psd.
#include<bits/stdc++.h>
using namespace std;
const int N=1500010;
struct node{
int son[2],fa,tot;
bool ans[2];
}s[N];
int a[N],n,q;
#define ls s[x].son[0]
#define rs s[x].son[1]
void upd(int x){
s[x].ans[0]=s[ls].ans[(s[rs].ans[0]+s[x].tot)/2];
s[x].ans[1]=s[ls].ans[(s[rs].ans[1]+s[x].tot)/2];
}
bool isrt(int x){return s[s[x].fa].son[0]!=x && s[s[x].fa].son[1]!=x;};
void rotate(int x){
int f=s[x].fa,ff=s[f].fa;
bool w=s[f].son[1]==x;
if(!isrt(f)) s[ff].son[s[ff].son[1]==f]=x;s[x].fa=ff;
s[f].son[w]=s[x].son[w^1];s[s[x].son[w^1]].fa=f;
s[f].fa=x;s[x].son[w^1]=f;
upd(f);upd(x);
}
void splay(int x){
while(!isrt(x)){
int f=s[x].fa,ff=s[f].fa;
if(!isrt(f)) s[ff].son[1]==f^s[f].son[1]==x?rotate(x):rotate(f);
rotate(x);
}
}
void acs(int x){
for(int las=0;x;las=x,x=s[x].fa)
splay(x),s[x].tot+=s[rs].ans[0]-s[las].ans[0],rs=las,upd(x);
}
void chg(int x,int t){acs(x);splay(x);s[x].tot+=t;upd(x);}
int main(){
scanf("%d",&n);
int x;s[0].ans[1]=1;
for(int i=1;i<=n;i++) for(int j=0;j<3;j++){scanf("%d",&x),s[x].fa=i;}
for(int i=n+1;i<=3*n+1;i++){
scanf("%d",&a[i]);
if(a[i]) chg(s[i].fa,1);
}
scanf("%d",&q);
while(q--){
scanf("%d",&x);a[x]^=1;
chg(s[x].fa,a[x]==1?1:-1);
printf("%d\n",s[s[x].fa].ans[0]);
}
}