BZOJ 3729 Gty的游戏 ——Splay
很久很久之前,看到Treap,好深啊
很久之前看到Splay,这数据结构太神了。
之后学习了LCT。
然后看到Top-Tree就更觉得神奇了。
知道我见到了这题,
万物基于Splay
显然需要维护子树查询,插入,子树修改。
Top-Tree?我不会。
直接用Splay维护欧拉序,然后拆成进入子树和离开两个节点,然后就可以方便的维护子树了。
本蒟蒻不会写,去hzwer抄了
#include <map> #include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define ll long long #define mp make_pair #define maxn 200005 int n,m,L,mod; int rt,ind,ynum,top; int val[maxn],fa[maxn],ch[maxn][2],typ[maxn],sg[maxn][2]; int a[maxn],st[maxn],dep[maxn],pos[maxn][2]; map <int,int> id; vector <int> e[maxn]; void update(int x) { int l=ch[x][0],r=ch[x][1]; sg[x][0]=sg[l][0]^sg[r][0]; sg[x][1]=sg[l][1]^sg[r][1]; sg[x][typ[x]]^=val[x]; } void rot(int x,int &k) { // printf("rot %d %d\n",x,k); int y=fa[x],z=fa[y],l,r; l=(ch[y][1]==x);r=l^1; if(y==k)k=x; else ch[z][ch[z][1]==y]=x; fa[ch[x][r]]=y;fa[y]=x;fa[x]=z; ch[y][l]=ch[x][r];ch[x][r]=y; update(y);update(x); } void splay(int x,int &k) { // printf("splay %d\n",x); while (x!=k) { int y=fa[x],z=fa[y]; if (y!=k) { if (ch[y][0]==x^ch[z][0]==y) rot(x,k); else rot(y,k); } rot(x,k); } } int build(int l,int r,int f) { if (l>r) return 0; int mid=(l+r)/2; if (st[mid]>0) { val[mid]=a[st[mid]]; pos[st[mid]][0]=mid; } else pos[-st[mid]][1]=mid; typ[mid]=dep[abs(st[mid])]; fa[mid]=f; ch[mid][0]=build(l,mid-1,mid); ch[mid][1]=build(mid+1,r,mid); update(mid); return mid; } void ins(int u,int v,int num) { splay(pos[u][0],rt); int t=ch[rt][1]; while (ch[t][0]) t=ch[t][0]; int t1=++top,t2=++top; pos[v][0]=t1;pos[v][1]=t2; fa[t1]=t;fa[t2]=t1; ch[t][0]=t1; ch[t1][1]=t2; val[t1]=num; typ[t1]=typ[t2]=dep[v]; update(t2);update(t1);splay(t2,rt); } void query(int x) { splay(pos[x][0],rt); splay(pos[x][1],ch[rt][1]); if (sg[ch[pos[x][1]][0]][dep[x]^1]) { ynum++; puts("MeiZ"); } else puts("GTY"); } void dfs(int x) { // printf("DFs %d\n",x); st[++top]=x; for (int i=0;i<e[x].size();++i) { dep[e[x][i]]=dep[x]^1; dfs(e[x][i]); } st[++top]=-x; } int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { // freopen("in.txt","r",stdin); n=read(); L=read(); mod=L+1; for (int i=1;i<=n;++i) { a[i]=read()%mod; id[i]=i; } for (int i=1;i<n;++i) { int u,v;u=read();v=read(); e[u].push_back(v); } dfs(1); rt=build(1,top,0); m=read(); int opt,u,v,x; while (m--) { opt=read(); if (opt==1) { v=read(); v^=ynum; query(id[v]); } if (opt==2) { x=read(); x^=ynum; v=read(); v^=ynum; v%=mod; x=id[x];splay(pos[x][0],rt);val[rt]=v; update(rt); } if (opt==3) { u=read(); u^=ynum; v=read(); v^=ynum; x=read(); x^=ynum; u=id[u]; id[v]=++n; dep[n]=dep[u]^1; ins(u,n,x%mod); } } }