题解:

lct

和上一题差不多

这一题还要判断是否有链接

其实直接并查集判断就可以了

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
const int N=100010;
using namespace std;
int read()
{
    int x=0;char ch=getchar();
    for (;ch<'0'||ch>'9';ch=getchar());
    for (;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x;
}
int n,m,top,cnt,c[N][2],fa[N],size[N],q[N],rev[N],f[N],sum[N],val[N],at[N],mt[N];
int isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void update(int x)
{
    int l=c[x][0],r=c[x][1];
    sum[x]=sum[l]+sum[r]+val[x];
    size[x]=size[l]+size[r]+1;
}
void pushdown(int x)
{
    int l=c[x][0],r=c[x][1];
    if (rev[x])
     {
        rev[x]^=1;rev[l]^=1;rev[r]^=1;
        swap(c[x][0],c[x][1]);
     }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],l,r;
    l=(c[y][1]==x);r=l^1;
    if (!isroot(y))c[z][c[z][1]==y]=x;
    fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
    c[y][l]=c[x][r];c[x][r]=y;
    update(y);update(x);
}
void down(int x){if (!isroot(x))down(fa[x]);pushdown(x);}
void splay(int x)
{
    down(x);
    for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
     if (!isroot(y))rotate((c[y][0]==x)==(c[fa[y]][0]==y)?y:x);
}
void access(int x)
{
    for(int t=0;x;t=x,x=fa[x])
     {
        splay(x);
        c[x][1]=t;
        update(x);
     }
}
void makeroot(int x){access(x);splay(x);rev[x]^=1;}
void split(int x,int y){makeroot(y);access(x);splay(x);}
void link(int x,int y){makeroot(x);fa[x]=y;}
int find(int x){if (x==f[x])return f[x];return f[x]=find(f[x]);}
int main()
{
    n=read();
    for (int i=1;i<=n;i++)val[i]=sum[i]=read(),f[i]=i,size[i]=1;
    m=read();char ch[50];
    while(m--)
     {
        scanf("%s",ch);
        int u=read(),v=read();
        if (ch[0]=='b')
         {
            if (f[find(u)]==f[find(v)])puts("no");
            else puts("yes"),link(u,v),f[find(u)]=f[find(v)];
         }
        if (ch[0]=='p')
         {
            val[u]=v;
            makeroot(u);
         }
        if (ch[0]=='e')
         {
             if (f[find(u)]!=f[find(v)])
              {
                  puts("impossible");
                  continue;
              }
            split(u,v);
            printf("%d\n",sum[u]);
         }
     }
    return 0;
}

 

posted on 2017-12-11 18:47  宣毅鸣  阅读(125)  评论(0编辑  收藏  举报