BZOJ3729: Gty的游戏

用splay维护DFS序

混着脑袋打了一发
调试了一天没搞出来
重打就好了。。。
然后本地跑得起来OJ上RE炸了。。
然后发现是maker打错了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
char c;
inline void read(int&a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
struct Node
{
    Node *lc,*rc,*f;
    Node *NearSon;
    Node *Aft,*Bef;
    int Odd,Lcc,Af;
    int data,height;
    inline bool l(){return f->lc==this;}
}*empty;
inline void Bg()
{
    empty=new Node;empty->lc=empty;empty->rc=empty;empty->f=empty;
    empty->Odd=0,empty->Lcc=0,empty->data=0;
}

map<int,int>Fir;
inline void updata(Node* x)
{
    int data=0;
    if(x->height&1)
      {
        if(x->lc!=empty)
           if(x->lc->height&1)
                data^=x->lc->Odd;
           else data^=x->lc->Lcc,data^=x->lc->data;
        if(x->rc!=empty)
           if(x->rc->height&1)
                data^=x->rc->Odd;
           else data^=x->rc->Lcc,data^=x->rc->data;
         x->Odd=data; 
         data=0;
         if(x->lc!=empty)
           if(x->lc->height&1)
                data^=x->lc->Lcc,data^=x->lc->data;
           else data^=x->lc->Odd;
        if(x->rc!=empty)
           if(x->rc->height&1)
                data^=x->rc->Lcc,data^=x->rc->data;
           else data^=x->rc->Odd;
         x->Lcc=data;
      }
    else
      {
        if(x->lc!=empty)
           if(x->lc->height&1)
                data^=x->lc->Lcc,data^=x->lc->data;
           else data^=x->lc->Odd;
        if(x->rc!=empty)
           if(x->rc->height&1)
                data^=x->rc->Lcc,data^=x->rc->data;
           else data^=x->rc->Odd;
         x->Odd=data; 
         data=0;
         if(x->lc!=empty)
           if(x->lc->height&1)
                data^=x->lc->Odd;
           else data^=x->lc->Lcc,data^=x->lc->data;
        if(x->rc!=empty)
           if(x->rc->height&1)
                data^=x->rc->Odd;
           else data^=x->rc->Lcc,data^=x->rc->data;
         x->Lcc=data;
      }
}
inline void Lc(Node *a)
{
    Node* f;
    if(a->f==a->f->f)
    f=a;
    else if(a->f->l())
      a->f->f->lc=a,f=a->f->f;
    else a->f->f->rc=a,f=a->f->f;
    a->rc->f=a->f;
    a->f->lc=a->rc;
    a->rc=a->f;
    a->f->f=a;
    a->f=f;
    updata(a->rc);
    updata(a);
}
inline void Rc(Node *a)
{
    Node* f;
    if(a->f==a->f->f)
    f=a;
    else if(a->f->l())
      a->f->f->lc=a,f=a->f->f;
    else a->f->f->rc=a,f=a->f->f;
    a->lc->f=a->f;
    a->f->rc=a->lc;
    a->lc=a->f;
    a->f->f=a;
    a->f=f;
    updata(a->lc);
    updata(a);
}
#define Turn Change
inline void Turn(Node *a){a->l()?Lc(a):Rc(a);}
inline void TwiChange(Node *a){a->l()==a->f->l()?Turn(a->f):Turn(a);Turn(a);}
inline void Splay(Node *a)
{
while(a->f->f!=a->f)
TwiChange(a);
while(a->f!=a)
Change(a);
}
inline void Splay2(Node *a)
{
    while(a->f->f->f!=a->f->f)TwiChange(a);
    while(a->f->f!=a->f)Change(a);
}
struct Chain
{
  int u;
  Chain *next;
  Chain(){next=NULL;}
}*Head[60001];
int tot;
Node *Old[60001];
int Con[60001];  
const
   int maxn=100001;
Node k[maxn];
int pos;
inline Node *New_Node()
{
    if(pos>maxn)pos=0;
    Node *tp=k+pos++;
    tp->lc=empty,tp->rc=empty,tp->data=tp->Lcc=tp->Odd=tp->height=0;
    return tp;
}
Node*Build(int u,int fa,int height)
{
    Node *New=New_Node();
    New->height=height;
    New->data=Con[u];
    Old[Fir[u]=++tot]=New;
    Node *l=New,*W;
    New->NearSon=New;
    for(Chain *tp=Head[u];tp;tp=tp->next)
     if(tp->u!=fa)
       {
         W=Build(tp->u,u,height+1);
         if(New->NearSon==New)New->NearSon=W;
         W->Bef=l;
         l=Old[tot];
       }
    New->Af=tot+1;
    return New;
}                                                                                                                                                                                                                                                                                                                                               

void Add(Node *a,int k,int x)
{
    Splay(a);
    Node *New=New_Node();
    New->height=a->height+1;
    New->Bef=a;
    New->Aft=a->Aft;
    New->data=x;
    New->Odd=New->Lcc=0;
    while(a->rc!=empty)Change(a->rc);
    a->rc=New,New->f=a;
    New->Aft=a->NearSon;
    a->NearSon->Bef=New;
    New->NearSon=New->Aft;
    a->NearSon=New;
    Old[Fir[k]=++tot]=New;
}
int Xor=0;
inline void Query(int x)
{
    int t=Fir[x];
    Node *Bf,*Af;
    Splay(Old[t]);
    Bf=Old[t]->Bef;
    Af=Old[t]->Aft;
    Splay(Bf);Splay2(Af);
    Node *p=Old[t];
    while(p->f!=Af)
    Change(p);
    puts(Af->lc->Odd?"MeiZ":"GTY");
   if(Af->lc->Odd)Xor++;
}
Node* MakeSplay(int l,int r)
{
    if(l>r)return empty;
    if(l^r)
    {
        int Mid=l+r>>1;
        Old[Mid]->lc=MakeSplay(l,Mid-1);
        Old[Mid]->rc=MakeSplay(Mid+1,r); 
        Old[Mid]->lc->f=Old[Mid];
        Old[Mid]->rc->f=Old[Mid];
        updata(Old[Mid]);
        Old[Mid]->Aft=Old[Old[Mid]->Af];
        if(Old[Mid]->NearSon==Old[Mid])
          Old[Mid]->NearSon=Old[Old[Mid]->Af];
        return Old[Mid];
    }
    Old[l]->lc=empty;
    Old[l]->rc=empty;
    Old[l]->Aft=Old[Old[l]->Af];
    if(Old[l]->NearSon==Old[l])
          Old[l]->NearSon=Old[Old[l]->Af];                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    return Old[l];
}

inline void Add(int u,int v)                                                                                                                                                                                                                                                                                                     
{
    Chain *tp=new Chain;
    tp->u=v;
    tp->next=Head[u];
    Head[u]=tp; 
}
int cnt=1;
map<int,int>P;
int main()
{
    int n,m,x,y,v,u,L,i,j,k;
    Bg();
    read(n),read(L);
    for(i=1;i<=n;i++)read(Con[i]),Con[i]%=L+1;
    P[1]=1;
    for(i=1;i<n;i++)
     {
      read(j),read(k);
      if(!P[j])P[j]=++cnt;if(!P[k])P[k]=++cnt;
       j=P[j],k=P[k];
       Add(j,k),Add(k,j);
     }
    Node *T,*Ac=empty;
    Node *A=New_Node(),*B=New_Node();
    B->data=B->Lcc=B->Odd=0;
    B->height=1<<29;
    A->data=B->Lcc=B->Odd=0;
    A->height=1<<29;
    Old[++tot]=A;
    T=Build(1,1,1);
    T->Bef=Old[1];
    Old[++tot]=B;
    Old[tot]->Af=tot;
    Old[1]->Af=1;
    T=MakeSplay(1,tot);
    T->f=T;
    read(m);
    while(m--)
    { 
        read(j);
        if(j==1)
          {
            read(k);k^=Xor;
            k=P[k];
            Query(k);
          }
        else if(j==2)
         {
            read(x),read(y);
            x^=Xor,y^=Xor;
            x=P[x];
            Node*t=Old[Fir[x]];
            y%=L+1;
             Splay(t);
            t->data=y;
         }
        else
          {
            read(u),read(v),read(x);
            u^=Xor,v^=Xor,x^=Xor;
            if(!P[u])P[u]=++cnt;
            if(!P[v])P[v]=++cnt;
            u=P[u],v=P[v];
             x%=L+1;
              Add(Old[Fir[u]],v,x);
          }
    }
    return 0;
}

你可能感兴趣的:(BZOJ3729: Gty的游戏)