BZOJ2843: 极地旅行社

裸LCT

#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;

struct Node
{
   Node *lc,*rc,*f;
   int data;
   int sum;
   bool Rev;
   Node *pl;
   inline bool h(){return f->lc==this||f->rc==this;}
   inline bool l(){return f->lc==this;}
};
Node *empty;
inline void Begin(){empty=new Node;empty->data=0,empty->sum=0,empty->lc=empty->rc=empty;empty->Rev=0;}
inline Node *New_Node(){Node *tp=new Node;tp->data=0,tp->sum=0,tp->lc=empty;tp->rc=empty;tp->Rev=0;return tp;}
inline void updata(Node *a){a->sum=a->lc->sum+a->rc->sum+a->data;}
inline void Lc(Node *a)
{
    Node *newf;
    if(a->f->f==a->f)
        newf=a;
    else if(!a->f->h())
        newf=a->f->f;
    else if(a->f->l()) 
        newf=a->f->f,a->f->f->lc=a;
    else 
        newf=a->f->f,a->f->f->rc=a;
    a->rc->f=a->f;
    a->f->lc=a->rc;
    a->rc=a->f;
    a->f->f=a;
    a->f=newf;
    updata(a->rc);
    updata(a);
}
inline void Rev(Node *a)
{Node *tp=a->lc;a->lc=a->rc;a->rc=tp;a->lc->Rev^=1,a->rc->Rev^=1,a->Rev^=1;}
inline void Rc(Node *a)
{
    Node *newf;
    if(a->f->f==a->f)
        newf=a;
    else if(!a->f->h())
        newf=a->f->f;
    else if(a->f->l()) 
        newf=a->f->f,a->f->f->lc=a;
    else 
        newf=a->f->f,a->f->f->rc=a;
    a->lc->f=a->f;
    a->f->rc=a->lc;
    a->lc=a->f;
    a->f->f=a;
    a->f=newf;
    updata(a->lc);
    updata(a);
}
inline void Change(Node *a)
{a->l()?Lc(a):Rc(a);}
inline void Twice_Change(Node *a)
{
    if(a->f->f->Rev)Rev(a->f->f);
    if(a->f->Rev)Rev(a->f);
    if(a->Rev)Rev(a);
    a->l()==a->f->l()?Change(a->f):Change(a);Change(a);
}
inline void Once_Change(Node *a)
{
    if(a->f->Rev)Rev(a->f);
    if(a->Rev)Rev(a);
    Change(a);
}
inline void Splay(Node *a)
{
    while(a->f->h()&&a->h())Twice_Change(a);
    while(a->h())Once_Change(a);
}

inline void Access(Node *a)
{
    while(true){Splay(a);if(a->f==a)return;if(a->f->Rev)Rev(a->f);Splay(a->f);a->f->rc=a;}
}
inline void MakeRoot(Node *a)
{
      Access(a);
      a->lc->Rev^=1,a->lc=empty;
      updata(a);
}

int F[100001]; int find(int x){return F[x]=(F[x]==x?x:find(F[x]));} inline void Union(int x,int y){F[find(x)]=F[find(y)];} Node S[100001]; 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(); } int main() { int n,m; read(n); Begin(); for(int i=1;i<=n;i++) S[i].pl=S+i,F[i]=i,read(S[i].data),S[i].sum=S[i].data,S[i].f=&S[i],S[i].lc=empty,S[i].rc=empty;; read(m); int x,y; for(int i=1;i<=m;i++) { do c=getchar();while(c!='b'&&c!='e'&&c!='p'); if(c=='b') { read(x),read(y); if(find(x)==find(y))puts("no"); else puts("yes"),Union(x,y),MakeRoot(&S[x]),S[x].f=&S[y]; } else if(c=='p') { read(x); read(S[x].data),MakeRoot(&S[x]); } else if(c=='e') { read(x),read(y); if(find(x)!=find(y)) puts("impossible"); else { MakeRoot(&S[x]); Access(&S[y]); printf("%d\n",S[y].lc->sum+S[y].data); } } } return 0; } 

你可能感兴趣的:(BZOJ2843: 极地旅行社)