BZOJ1180 [CROATIAN2009]OTOCI

    裸LCT。。 不知为何单旋splay比双旋快。。。。

    

#include 
#include 
#include 
using namespace std;
struct node
{
    node *l,*r,*f;
    int val,sum,flip;
    node(){l=r=f=NULL;flip=0;sum=val=0;}
    node(int _val) {l=r=f=NULL;sum=val=_val;flip=0;}
};
node *tree[100000];
inline bool isroot(node *u) {return ((!u->f)||(u->f->l!=u&&u->f->r!=u));}
inline void update(node *u)
{
    u->sum=u->val;
    if (u->l) u->sum+=u->l->sum;
    if (u->r) u->sum+=u->r->sum;
}
inline void down(node *p)
{
    if (p->flip)
    {
        p->flip=0;
        if (p->l) p->l->flip^=1;
        if (p->r) p->r->flip^=1;
        swap(p->l,p->r);
    }
}
void zig(node *u)
{
    node *x=u->f,*y=x->f;
    u->f=y;x->f=u;
    if (y)
    {
        if (y->l==x) y->l=u;
        else if (y->r==x) y->r=u;
    }
    x->l=u->r;if (x->l) x->l->f=x;
    u->r=x;
    update(x);
}
void zag(node *u)
{
    node *x=u->f,*y=x->f;
    u->f=y;x->f=u;
    if (y)
    {
        if (y->l==x) y->l=u;
        else if (y->r==x) y->r=u;
    }
    x->r=u->l;if (x->r) x->r->f=x;
    u->l=x;
    update(x);
}
void push_down(node *p) {if (!isroot(p)) push_down(p->f); down(p);}
void splay(node *p)
{
    push_down(p);
    while (!isroot(p))
    {
        node *x=p->f;
        if (x->l==p) zig(p);
           else zag(p);
    }
    update(p);
}
node* expose(node *p)
{
    node *q;
    for (q=NULL;p;p=p->f)
    {
        splay(p);
        p->r=q;
        update(q=p);
    }
    return q;
}
node *root(node *p)
{
    node *u=expose(p);
    down(u);
    while (u->l)
    {
        u=u->l;
        down(u);
    }
    return u;
}
void evert(node *p)
{
    expose(p);
    splay(p);
    p->flip^=1;
}
int n,m;
int main()
{
    cin>>n;
    for (int i=1;i<=n;++i)
    {
        int x;
        scanf("%d",&x);
        tree[i]=new node(x);
    }
    cin>>m;
    while (m--)
    {
        char com[20];
        int a,b;
        scanf("%s",com);
        scanf("%d%d",&a,&b);
        if (com[0]=='b')
        {
            if (root(tree[a])==root(tree[b])) printf("no\n");
            else {printf("yes\n");evert(tree[a]);tree[a]->f=tree[b];}
        }
        else if (com[0]=='p')
        {
            splay(tree[a]);
            tree[a]->val=b;
        }
        else
        {
            if (root(tree[a])!=root(tree[b])) printf("impossible\n");
            else {
                int ans=0;
                ans+=expose(tree[a])->sum;
                node *p=expose(tree[b]);
                ans+=p->sum;
                ans-=2*(expose(p)->sum);
                printf("%d\n",ans+p->val);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(problems)