BZOJ3729: Gty的游戏

来源:互联网 发布:网络代刷信誉兼职中心 编辑:程序博客网 时间:2024/06/07 16:21

易知sg值=石子数%(L+1)
树上的阶梯博弈,需要维护每个点子树内奇数层(相对询问节点)sg的异或和,因为兹瓷插入,所以用splay维护dfs序,每个节点开2个节点,子树内的点插入到这两点之间
询问时如果询问的是奇数层的点的子树,那就是偶数层(相对树根)的异或和,所以要维护子树内奇数层异或和和偶数层异或和
替罪羊树跑的飞快

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define A 0.73using namespace std;inline void read(int &x){    char c; while(!((c=getchar())>='0'&&c<='9'));    x=c-'0'; while((c=getchar())>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0';}const int maxn = 120000;int n,m,L,w;int s[maxn],dep[maxn];struct Goat{    int fa,son[2],siz,c[2],x;}tr[maxn<<2]; int root;int ti[maxn];inline void pushup(const int &x){    int &lc=tr[x].son[0],&rc=tr[x].son[1];    tr[x].c[0]=tr[lc].c[0]^tr[rc].c[0];    tr[x].c[1]=tr[lc].c[1]^tr[rc].c[1];    if(x&1) tr[x].c[dep[tr[x].x]&1]^=s[tr[x].x];}int id[maxn],cnt;void dfs(const int &x){    if(tr[x].son[0]) dfs(tr[x].son[0]),tr[x].son[0]=0;    id[++cnt]=x;    if(tr[x].son[1]) dfs(tr[x].son[1]),tr[x].son[1]=0;}int build(const int l,const int r,const int ff){    int mid=l+r>>1,x=id[mid];    tr[x].siz=r-l+1; tr[x].fa=ff;    if(l!=mid) tr[x].son[0]=build(l,mid-1,x);    if(mid!=r) tr[x].son[1]=build(mid+1,r,x);    pushup(x);    return x;}int rebuild(int x){    cnt=0; dfs(x);    int ff=tr[x].fa,t=tr[ff].son[1]==x;    x=build(1,cnt,ff);    tr[ff].son[t]=x;    return x;}int bal;void ins(const int u,const int v){    int x=(u<<1)-1,y=(v<<1)-1,y2=y+1;    int t=dep[v]&1;    if(!tr[x].son[1]) tr[x].son[1]=y;    else    {        x=tr[x].son[1]; while(tr[x].son[0]) x=tr[x].son[0];        tr[x].son[0]=y;    }    tr[y].fa=x; tr[y].son[1]=y2;    tr[y].siz=2; tr[y].x=v; tr[y].c[t]=s[v];    tr[y2].fa=y; tr[y2].siz=1; tr[y2].x=v;    for(int i=x;i;i=tr[i].fa)    {        tr[i].c[t]^=s[v];        tr[i].siz+=2;        if(tr[tr[i].son[0]].siz>A*tr[i].siz||tr[tr[i].son[1]].siz>A*tr[i].siz) bal=i;    }}inline void mark(int x){while(x)     ti[x]=m+1,x=tr[x].fa;}int query(const int u){    int x=2*u-1,y=u<<1;    int t=dep[u]&1^1;    int ans=0;    mark(y); int mul=x;    if(ti[x]!=m+1)     {        ans^=tr[tr[x].son[1]].c[t];        for(int la=x,i=tr[x].fa;i;la=i,i=tr[i].fa)        {            if(ti[i]==m+1)             {                 if((i&1)&&(dep[tr[i].x]&1)==t) ans^=s[tr[i].x];                mul=i; break;             }            if(la==tr[i].son[0])             {                if((i&1)&&(dep[tr[i].x]&1)==t) ans^=s[tr[i].x];                ans^=tr[tr[i].son[1]].c[t];            }        }    }    if(mul!=y)    {        ans^=tr[tr[y].son[0]].c[t];        for(int la=y,i=tr[y].fa;i!=mul;la=i,i=tr[i].fa)             if(la==tr[i].son[1])             {                if((i&1)&&(dep[tr[i].x]&1)==t) ans^=s[tr[i].x];                ans^=tr[tr[i].son[0]].c[t];            }    }    return ans;}void upd(const int u,const int c){    int x=(u<<1)-1;    int t=dep[u]&1;    s[u]^=c;    for(int i=x;i;i=tr[i].fa) tr[i].c[t]^=s[u];    s[u]=c;}struct edge{    int y,nex;    edge(){}    edge(const int _y,const int _nex){y=_y;nex=_nex;}}a[maxn<<1]; int len,fir[maxn];inline void insert(const int x,const int y){a[++len]=edge(y,fir[x]);fir[x]=len;}void B_T(const int x,const int ff){    tr[id[++cnt]=x*2-1].x=x;    for(int k=fir[x];k;k=a[k].nex) if(a[k].y!=ff)        dep[a[k].y]=dep[x]+1,B_T(a[k].y,x);    tr[id[++cnt]=x<<1].x=x;}int main(){    read(n); read(L);    for(int i=1;i<=n;i++) read(s[i]),s[i]%=(L+1);    for(int i=1;i<n;i++)    {        int x,y; read(x); read(y);        insert(x,y); insert(y,x);    }    cnt=0; dep[1]=1;     B_T(1,0); root=build(1,cnt,0);    read(m); int dec=0;    while(m--)    {        int k; read(k);        if(k==1)        {            int x; read(x); x^=dec;            //query            if(query(x)) dec++,puts("MeiZ");            else puts("GTY");        }        else if(k==2)        {            int x,y; read(x);read(y);            x^=dec; y^=dec; y%=(L+1);            //upd            upd(x,y);        }        else        {            int u,v,x; read(u); read(v); read(x);            u^=dec; v^=dec; x^=dec; x%=(L+1);            s[v]=x; dep[v]=dep[u]+1;            //ins            bal=0; ins(u,v);            if(!bal) continue;            if(bal==root) root=rebuild(root);            else rebuild(bal);        }    }    return 0;}
0 0
原创粉丝点击