uoj279温暖会指引我们前行

暖气来啦~

动态树维护最大生成树裸题

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=400010;
int es[maxn][2];
int n,m;
int rt,Size;
struct LCT
{
    int son[maxn][2],f[maxn],val[maxn],size[maxn],cnt[maxn],rev[maxn],st[maxn];
    int t[maxn],len[maxn],mn[maxn],sum[maxn];
    inline void update(int x)
    {
        int &o=x,lch=son[x][0],rch=son[x][1];
        mn[o]=x;sum[o]=len[o];
        if(son[x][0])
        {
            if(t[mn[lch]]<t[mn[x]]) mn[o]=mn[lch];
            sum[o]+=sum[lch];
        }
        if(son[x][1])
        {
            if(t[mn[rch]]<t[mn[x]]) mn[o]=mn[rch];
            sum[o]+=sum[rch];
        }
    }
    inline int isroot(int x){return son[f[x]][0]!=x && son[f[x]][1]!=x;}
    inline void rotate(int x)
    {
        int y=f[x],z=f[y],l,r;
        if(son[y][0]==x)l=0;
        else l=1;r=l^1;
        if(!isroot(y))
        {
            if(son[z][0]==y)son[z][0]=x;
            else son[z][1]=x;
        }
        f[x]=z;f[y]=x;f[son[x][r]]=y;
        son[y][l]=son[x][r];son[x][r]=y;
        update(y);
    }
    inline void pushdown(int id)
    {
        int lch=son[id][0],rch=son[id][1];
        if(rev[id])
        {
            rev[id]^=1;rev[lch]^=1;rev[rch]^=1;
            swap(son[id][0],son[id][1]);
        }
    }
    inline void Splay(int x)
    {
        int top=0;st[++top]=x;
        for(int i=x;!isroot(i);i=f[i])st[++top]=f[i];
        for(int i=top;i;i--)pushdown(st[i]);
        while(!isroot(x))
        {
            int y=f[x],z=f[y];
            if(!isroot(y))
            {
                if(son[y][0]==x^son[z][0]==y)rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        update(x);
    }
    inline void access(int x)
    {
        int t=0;
        while(x)
        {
            Splay(x);
            son[x][1]=t;
            t=x;
            x=f[x];
            update(x);
        }
    }
    inline void makert(int x){access(x);Splay(x);rev[x]^=1;}
    inline void link(int x,int y){makert(x);f[x]=y;}
    inline void cut(int x,int y){makert(x);access(y);Splay(y);son[y][0]=f[x]=0;update(y);}
    inline int findf(int x)
    {
        access(x);Splay(x);
        int y=x;
        while(son[y][0])y=son[y][0];
        return y;
    }
}Tree;
char opt[10];
int main()
{
    scanf("%d%d",&n,&m);
    int k,x,y,z;
    for(int i=1;i<=n;i++)Tree.t[i]=2147483233;
    while(m--)
    {
        scanf("%s",opt);
        if(opt[0]=='f')
        {
            scanf("%d%d%d",&z,&x,&y);z++,x++,y++;
            z+=n;es[z][0]=x,es[z][1]=y;
            scanf("%d%d",&Tree.t[z],&Tree.len[z]);
            if(Tree.findf(x)!=Tree.findf(y)){Tree.link(z,x),Tree.link(z,y);}
            else
            {
                Tree.makert(x);Tree.access(y);Tree.Splay(y);
                if(Tree.t[Tree.mn[y]]<Tree.t[z])
                {
                    k=Tree.mn[y];Tree.cut(k,es[k][0]);Tree.cut(k,es[k][1]);
                    Tree.link(z,x),Tree.link(z,y);
                }
            }
        }
        else if(opt[0]=='m')
        {
            scanf("%d%d",&x,&y);x++,y++;
            if(Tree.findf(x)!=Tree.findf(y))puts("-1");
            else
            {
                Tree.makert(x);Tree.access(y);Tree.Splay(y);
                printf("%d\n",Tree.sum[y]);
            }
        }
        else 
        {
            scanf("%d%d",&x,&y);x++;
            x+=n;Tree.Splay(x);Tree.len[x]=y;Tree.update(x);
        }
    }
}
View Code

 

posted @ 2017-12-05 13:42  探险家Mr.H  阅读(183)  评论(0编辑  收藏  举报