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);
        }
    }
}

  

posted @ 2017-04-20 11:14  SfailSth  阅读(163)  评论(0编辑  收藏  举报