uoj274 温暖会指引我们前行

显然只需要维护最大生成树,LCT即可。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=800010;
void pause()
{

}
int rd()
{
    int x=0;
    char c=getchar();
    while (c<'0'||c>'9') c=getchar();
    while (c>='0'&&c<='9')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    return x;
}
char rdc()
{
    char c=getchar();
    while (c<'a'||c>'z') c=getchar();
    return c;
}
int fa[maxn],son[maxn][2],sum[maxn],mnid[maxn],inv[maxn],u[maxn],v[maxn],t[maxn],l[maxn],sta[maxn],in[maxn],
n,q,tot;
void down(int u)
{
    if (inv[u])
    {
        swap(son[u][0],son[u][1]);
        if (son[u][0]) inv[son[u][0]]^=1;
        if (son[u][1]) inv[son[u][1]]^=1;
        inv[u]=0;
    }
}
void up(int u)
{
    sum[u]=sum[son[u][0]]+sum[son[u][1]]+(u>n?l[u-n]:0);
    if (mnid[son[u][0]]!=-1&&(mnid[son[u][1]]==-1||t[mnid[son[u][0]]]<t[mnid[son[u][1]]])) mnid[u]=mnid[son[u][0]];
    else mnid[u]=mnid[son[u][1]];
    if (u>n&&(mnid[u]==-1||t[u-n]<t[mnid[u]])) mnid[u]=u-n;
}
int isroot(int u)
{
    return son[fa[u]][0]!=u&&son[fa[u]][1]!=u;
}
void rot(int u,int f)
{
    int v=son[u][f],x=son[v][f^1],y=fa[u];
    if (son[y][0]==u) son[y][0]=v;
    if (son[y][1]==u) son[y][1]=v;
    fa[v]=y;
    son[v][f^1]=u;
    fa[u]=v;
    son[u][f]=x;
    if (x) fa[x]=u;
    up(u);
    up(v);
}
void splay(int u)
{
    int t=u,x,fx,y,fy,top=0;
    while (t)
    {
        sta[++top]=t;
        if (isroot(t)) break;
        t=fa[t];
    }
    for (;top;top--)
        down(sta[top]);
    while (!isroot(u))
    {
        x=fa[u];
        fx=son[x][1]==u;
        if (isroot(x)) rot(x,fx);
        else
        {
            y=fa[x];
            fy=son[y][1]==x;
            if (fx==fy) rot(y,fy),rot(x,fx);
            else rot(x,fx),rot(y,fy);
        }
    }
}
void access(int u)
{
    int v=0,t=u;
    while (u)
    {
        splay(u);
        son[u][1]=v;
        if (v) fa[v]=u;
        up(u);
        v=u;
        u=fa[u];
    }
    splay(t);
}
void makeroot(int u)
{
    access(u);
    inv[u]=1;
}
void link(int u,int v)
{
    makeroot(u);
    fa[u]=v;
}
void cut(int u,int v)
{
    makeroot(u);
    access(v);
    fa[u]=son[v][0]=0;
    up(v);
}
int main()
{
    //freopen("b.in","r",stdin);
    int x,y,id;
    char c;
    n=rd();
    q=rd();
    for (int i=0;i<=n;i++) mnid[i]=-1;
    while (q--)
    {
        c=rdc();
        if (c=='f')
        {
            id=rd()+1;
            //if (id==2) pause();
            mnid[id+n]=-1;
            u[id]=rd()+1;
            v[id]=rd()+1;
            t[id]=rd();
            l[id]=rd();
            sum[id+n]=l[id];
            mnid[id+n]=id;
            makeroot(u[id]);
            access(v[id]);
            if (!isroot(u[id]))
            {
                x=mnid[v[id]];
                if (t[id]>t[x])
                {
                    cut(u[id],x+n);
                    cut(v[id],x+n);
                    link(u[id],id+n);
                    link(v[id],id+n);
                    in[x]=0;
                    in[id]=1;
                }
            }
            else
            {
                link(u[id],id+n);
                link(v[id],id+n);
                in[id]=1;
            }
        }
        else if (c=='m')
        {
            x=rd()+1;
            y=rd()+1;
            if (x==y)
            {
                printf("0\n");
                continue;
            }
            makeroot(x);
            access(y);
            if (!isroot(x)) printf("%d\n",sum[y]);
            else printf("-1\n");
        }
        else
        {
            id=rd()+1;
            x=rd();
            if (in[id])
            {
                cut(u[id],id+n);
                cut(v[id],id+n);
                sum[id+n]=l[id]=x;
                link(u[id],id+n);
                link(v[id],id+n);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/sdfzyhx/article/details/75319479