可以看成巴什博弈和NIM的游戏
权值全部对L+1取模,然后只看子树中奇数层的亦或和是不是零就可以了。
因为强制在线,所以只能有Splay来维护DFS序
#include
#include
#include
#include
using namespace std;
const int N=500010;
map<int,int> M;
int G[N],w[N],dpt[N];
int n,m,lst,cnt,iL;
struct edge{
int t,nx;
}E[N];
struct NODE{
NODE *l,*r,*f;
int val[2],w,dpt;
NODE(){ val[0]=val[1]=w=dpt=0; l=r=f=0; }
}a[N],*L[N],*R[N];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void fix(int &x){
if(!M.count(x)) M[x]=++cnt;
x=M[x];
}
int cnt0;
inline void Insert(int x,int y){
E[++cnt0].t=y; E[cnt0].nx=G[x]; G[x]=cnt0;
E[++cnt0].t=x; E[cnt0].nx=G[y]; G[y]=cnt0;
}
int Q[N],t;
void dfs(int x,int f){
Q[++t]=x; L[x]=a+t; dpt[x]=dpt[f]+1;
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=f) dfs(E[i].t,x);
t++; R[x]=a+t;
}
inline void Up(NODE *x){
if(!x) return ;
x->val[0]=x->val[1]=0;
x->val[(x->dpt)&1]=x->w;
if(x->l)
x->val[0]^=x->l->val[0],x->val[1]^=x->l->val[1];
if(x->r)
x->val[0]^=x->r->val[0],x->val[1]^=x->r->val[1];
}
inline void rotatel(NODE *x){
NODE *y=x->f,*z=y->f;
if(z) if(z->l==y) z->l=x; else z->r=x;
x->f=z;
if(y->l=x->r) y->l->f=y;
x->r=y; y->f=x;
Up(y); Up(x);
}
inline void rotater(NODE *x){
NODE *y=x->f,*z=y->f;
if(z) if(z->l==y) z->l=x; else z->r=x;
x->f=z;
if(y->r=x->l) y->r->f=y;
x->l=y; y->f=x; Up(y); Up(x);
}
inline void splay(NODE *x,NODE *t){
while(x->f!=t){
NODE *y=x->f,*z=y->f;
if(x==y->l){
if(z && z->l==y && z!=t) rotatel(y);
rotatel(x);
}
else{
if(z && z->r==y && z!=t) rotater(y);
rotater(x);
}
}
}
inline int Query(int x){
splay(L[x],0);
splay(R[x],L[x]);
return R[x]->l?R[x]->l->val[(dpt[x]&1)^1]:0;
}
inline NODE *pre(NODE *x){
if(x->l){
x=x->l;
while(x->r) x=x->r;
return x;
}
while(x==x->f->l) x=x->f;
return x->f;
}
void PUTS(NODE *x){
if(x->l) PUTS(x->l);
printf("%d ",x->w);
if(x->r) PUTS(x->r);
}
int main(){
rea(n); rea(iL); iL++; cnt=n;
for(int i=1;i<=n;i++)
rea(w[i]),w[i]%=iL,M[i]=i;
for(int i=1,x,y;i1,0);
for(int i=2;i<=t;i++)
a[i-1].r=a+i,a[i].f=a+i-1;
for(int i=t;i;i--)
a[i].w=w[Q[i]],a[i].dpt=dpt[Q[i]],Up(a+i);
rea(m);
while(m--){
int opt,u,v,x;
rea(opt);
if(opt==1){
rea(v); v^=lst;
fix(v);
puts(Query(v)?(lst++,"MeiZ"):"GTY");
}
else if(opt==2){
rea(u); rea(x); u^=lst; x^=lst;
fix(u);
splay(L[u],0); L[u]->w=x%iL; Up(L[u]);
}
else{
rea(u); rea(v); rea(x);
u^=lst; v^=lst; x^=lst;
fix(u); fix(v);
dpt[v]=dpt[u]+1;
t++; L[v]=a+t;
t++; R[v]=a+t;
L[v]->dpt=dpt[v]; L[v]->w=x%iL;
L[v]->r=R[v]; R[v]->f=L[v];
NODE *cur=pre(R[u]);
splay(cur,0);
splay(R[u],cur);
R[u]->l=L[v]; L[v]->f=R[u]; Up(R[u]); Up(cur);
splay(L[v],0);
}
//NODE *s;
//for(int i=1;i<=t;i++) if(!a[i].f) s=a+i;
//PUTS(s); putchar('\n');
}
return 0;
}