BZOJ2843: 极地旅行社

来源:互联网 发布:java id 生成 与还原 编辑:程序博客网 时间:2024/06/08 09:17

裸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;}
0 0
原创粉丝点击