• [2016北京集训试题14]股神小D-[LCT]


    Description

    Solution

    将(u,v,l,r)换为(1,u,v,l)和(2,u,v,r)。进行排序(第4个数为第一关键字,第1个数为第二关键字)。用LCT维护联通块的合并和断开。(维护联通块的大小,要维护虚边)

    答案统计:每当四元组的第一个数为1(这时候合并点u,v所在连通块,反之拆开),在合并前ans+=size[u]*size[v]即可。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int N=2e5+10;
    long long ans;
    struct LCT
    {
        int val[N],sz[N],v[N],fa[N],ch[N][2],rev[N];
        bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
        bool get(int x){return ch[fa[x]][1]==x;}
        void updata(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+v[x]+1;}
        void rotate(int x)
        {
            int k=get(x),y=fa[x];
            ch[y][k]=ch[x][k^1];fa[ch[y][k]]=y;
            if (!isroot(y)) ch[fa[y]][ch[fa[y]][1]==y]=x;fa[x]=fa[y];
            fa[y]=x;ch[x][k^1]=y;
            updata(y);
            updata(x);  
        }
        void pushdown(int x)
        {
            if (rev[x])
            {
                swap(ch[x][0],ch[x][1]);
                rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;
                rev[x]=0;
            }
        }
        int q[N],cnt;
        void splay(int x)
        {
            int y;
            q[cnt=1]=x;
            for (int i=x;!isroot(i);i=fa[i]) q[++cnt]=fa[i];
            for (int i=cnt;i>=1;i--) pushdown(q[i]),fa[q[i]]=fa[q[i]];
            while (!isroot(x))
            {
                y=fa[x];
                if (!isroot(y)) rotate(get(x)==get(y)?y:x);
                rotate(x);
            }
        }
        void access(int x)
        {
            int y=0;
            while (x)
            {
                splay(x);
                v[x]+=sz[ch[x][1]]-sz[y];
                ch[x][1]=y;
                updata(x);
                y=x;x=fa[x];
            }
        }
        void mroot(int x)
        {
            access(x);splay(x);rev[x]^=1;
        }
        void link(int x,int y)
        {
            mroot(x);access(y);splay(y);
            ans+=1ll*sz[x]*sz[y];
            fa[x]=y;v[y]+=sz[x];updata(y);
        }
        void cut(int x,int y)
        {
            mroot(x);access(y);splay(y);
            fa[x]=ch[y][0]=0;
            updata(y);
        }
    }lct;
    int n,u,v,l,r;
    struct Q{int t,u,v,w;
        friend bool operator <(Q a,Q b){return a.w==b.w?a.t<b.t:a.w<b.w;}
    }q[N<<1];
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<n;i++)
        {
            scanf("%d%d%d%d",&u,&v,&l,&r);
            q[i*2-1]=Q{1,u,v,l};q[i*2]=Q{2,u,v,r};
        }
        sort(q+1,q+2*n-1);
        for (int i=1;i<=2*n-2;i++)
        {
            if (q[i].t==1) lct.link(q[i].u,q[i].v);
            else lct.cut(q[i].u,q[i].v);
        }
        cout<<ans;
    }
  • 相关阅读:
    8.使用axios实现登录功能
    7.django配置跨域并开发测试接口
    9.Vue组件
    2.初始化项目结构
    1.Django基础
    团队冲刺——第七天
    团队冲刺——第六天
    十天冲刺——第五天
    十天冲刺——第四天
    十天冲刺——第三天
  • 原文地址:https://www.cnblogs.com/coco-night/p/9696166.html
Copyright © 2020-2023  润新知