我们知道,每一个\(x_{i}\)各不相同。这启发我们,这一题的点将形成一棵树的结构。
仔细观察题目描述,我们发现,对于每一个点,它的修改影响到的有且仅有它的祖先。
我们不妨设一个点的权值为它的子节点们中信号为1的个数。那么根据题目给出的性质,当且仅当某个节点的权值为1的时候它的某个0子节点变成1,或者某个节点的权值为2的时候它的某个1子节点变成0,这个信号才会继续向上传输。容易发现,这样的传输覆盖的是且总是某一条竖直上下的全1/全2链。
详细地说,如果修改的叶子节点是0变成1,那么影响到的就是从它拉出的一条竖直向上的全1链以及这条链的父亲;如果修改的叶子节点是1变成0,那么影响到的就是从它拉出的一条竖直向上的全2链以及这条链的父亲。
因此,我们可以考虑在LCT剖出的实链上维护全1链以及全2链,然后修改的时候修改一整条链。这就完成了这题的要求。
但是仔细想想,我们会发现,维护全1链和全2链会显得很麻。所以我们不妨改为维护深度最深的非1节点和非2节点。对于将0变为1的操作,我们找到深度最深的非1节点,把它旋到根,然后修改即可,如果深度最深的非1节点不存在,那就意味着根节点也是1,那么答案就会发生变化;对于将1变为0的操作,如法炮制。
另外,由于这一题只有竖直上下的链的操作,所以我们甚至不需要写换根函数。当然,由于这一题没有分离和合并操作,因此,我们也不需要写分离和合并函数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
inline void Swap(int &A,int &B){
A^=B^=A^=B;
}
const int N=500005;
int fa[N*3],ch[N*3][2],val[N*3],n1[N*3],n2[N*3],lzy[N*3];
//先看右子节点(下方)是否存在,再看本节点是否满足要求,然后看左子节点(上方)是否存在。
inline void updt(int X){
n1[X]=n1[ch[X][1]]?n1[ch[X][1]]:(val[X]==1?n1[ch[X][0]]:X);
n2[X]=n2[ch[X][1]]?n2[ch[X][1]]:(val[X]==2?n2[ch[X][0]]:X);
}
inline void rnw(int X,int V){
val[X]^=3,Swap(n1[X],n2[X]),lzy[X]+=V;
}
inline void pshd(int X){
if(lzy[X]!=0){
rnw(ch[X][0],lzy[X]);rnw(ch[X][1],lzy[X]);lzy[X]=0;
}
}
inline bool fndD(int X){
return ch[fa[X]][1]==X;
}
inline bool ntrt(int X){
return ch[fa[X]][0]==X||ch[fa[X]][1]==X;
}
inline void splayOne(int X){
int Y=fa[X],Z=fa[Y],D=fndD(X),D2=fndD(Y),C=ch[X][D^1];
if(ntrt(Y)){
ch[Z][D2]=X;
}
ch[X][D^1]=Y,ch[Y][D]=C;
if(C){
fa[C]=Y;
}
fa[Y]=X,fa[X]=Z;
updt(Y),updt(X);
}
int st[N*3];
inline void splay(int X){
int Y=X,Z=0;
st[++Z]=Y;
while(ntrt(Y)){
Y=fa[Y];
st[++Z]=Y;
}
while(Z){
pshd(st[Z--]);
}
while(ntrt(X)){
Y=fa[X],Z=fa[Y];
if(ntrt(Y)){
splayOne(fndD(X)^fndD(Y)?X:Y);
}
splayOne(X);
}
}
inline void access(int X){
for(int Y=0;X;Y=X,X=fa[X]){
splay(X),ch[X][1]=Y,updt(X);
}
}
int n,Q,in[N*3];
std::queue<int> q;
void init(){
scanf("%d",&n);
int x,y,z;
for(int i=1;i<=n;++i){
scanf("%d%d%d",&x,&y,&z);
fa[x]=fa[y]=fa[z]=i;
in[i]=3;
}
for(int i=1;i<=(n<<1|1);++i){
scanf("%d",&x);
q.push(i+n);
val[i+n]=x<<1;
}
while(!q.empty()){
x=q.front();
q.pop();
if(x<=n){
updt(x);
}
val[fa[x]]+=val[x]>>1;
--in[fa[x]];
if(!in[fa[x]]){
q.push(fa[x]);
}
}
scanf("%d",&Q);
int tp,nwrt=val[1]>>1;
for(int i=1;i<=Q;++i){
scanf("%d",&x);
tp=(val[x]^=2)-1;
x=fa[x];
access(x),splay(x);
if((~tp?n1:n2)[x]){
x=(~tp?n1:n2)[x];
splay(x);
rnw(ch[x][1],tp),updt(ch[x][1]);
val[x]+=tp;updt(x);
}else{
rnw(x,tp);updt(x);
nwrt^=1;
}
puts(nwrt?"1":"0");
}
}
int main(){
init();
return 0;
}