BZOJ 1180 OTOCI

LCT。模板还是不熟啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxv 30050
using namespace std;
int n,w[maxv],val[maxv],tree[maxv][3],fath[maxv],stack[maxv],cnt=0,a,b,q,rev[maxv];
char type[20];
bool isroot(int x)
{
    return (tree[fath[x]][1]!=x) && (tree[fath[x]][2]!=x);
}
void pushup(int x)
{
    int ls=tree[x][1],rs=tree[x][2];
    val[x]=val[ls]+val[rs]+w[x];
}
void pushdown(int x)
{
    if (rev[x])
    {
        int ls=tree[x][1],rs=tree[x][2];
        rev[x]=0;rev[ls]^=1;rev[rs]^=1;
        swap(tree[x][1],tree[x][2]);
    }
}
void rotate(int x)
{
    int y=fath[x],z=fath[y],l,r;
    if (tree[y][1]==x) l=1;else l=2;
    r=3-l;
    if (!isroot(y))
    {
        if (tree[z][1]==y) tree[z][1]=x;
        else tree[z][2]=x;
    }
    fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
    tree[y][l]=tree[x][r];tree[x][r]=y;
    pushup(y);pushup(x);
}
void splay(int x)
{
    int y=fath[x],z=fath[y];
    cnt=0;stack[++cnt]=x;
    for (int i=x;!isroot(i);i=fath[i])
        stack[++cnt]=fath[i];
    for (int i=cnt;i>=1;i--) pushdown(stack[i]);
    while (!isroot(x))
    {
        int y=fath[x],z=fath[y];
        if (!isroot(y))
        {
            if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
}
void access(int x)
{
    int regis=0;
    while (x)
    {
        splay(x);tree[x][2]=regis;
        pushup(x);regis=x;x=fath[x];
    }
}
void makeroot(int x)
{
    access(x);splay(x);rev[x]^=1;
}
void link(int x,int y)
{
    makeroot(x);
    fath[x]=y;
}
int find(int x)
{
    access(x);splay(x);
    int y=x;
    while (tree[y][1]) y=tree[y][1];
    return y;
}
int split(int x,int y)
{
    makeroot(x);access(y);splay(y);
    return val[y];
}
void work1()
{
    scanf("%d%d",&a,&b);
    if (find(a)!=find(b)) 
    {
        printf("yes
");
        link(a,b);
    }
    else printf("no
");
}
void work2()
{
    scanf("%d%d",&a,&b);
    access(a);splay(a);
    w[a]=b;pushup(a);
}
void work3()
{
    scanf("%d%d",&a,&b);
    if (find(a)!=find(b)) printf("impossible
");
    else printf("%d
",split(a,b));
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&w[i]);
        val[i]=w[i];
    }
    scanf("%d",&q);
    for (int i=1;i<=q;i++)
    {
        scanf("%s",type);
        if (type[0]=='b') work1();
        else if (type[0]=='p') work2();
        else work3();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/5466225.html