zoukankan      html  css  js  c++  java
  • All men are brothers

    All men are brothers

    牛客多校第九场E

    给定n个人,起初互不认识

    然后m各阶段

    每个阶段有两个人x、y认识

    求每个阶段选出四个人互不认识的方式

    并查集

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    ll f[100004];
    ll siz[100005];
    ///维护当前连通分支大小
    
    ll n,m;
    ll K;
    ll tm=0;///所有连通分支大小的平方求和
    void init()
    {
        for(ll i=1;i<=n;i++){
            f[i]=i;
            siz[i]=1;
            tm++;
        }
    }
    ll cal(ll n)///算C (n,4)
    {
       ll ans=(ll)(((n*(n-1))/2*(n-2))/3*(n-3))/4;
       return ans;
    }
    ll get(int x)
    {
        return f[x]=(f[x]==x? x:get(f[x]));
    }
    ll uni(int x,int y)
    {
        int a=get(x);
        int b=get(y);
        if(a==b)return 0;///连通分支个数不变,对答案不产生贡献
        ///两个连通分支合并
        ///产生的影响:原来答案中,可能选了一个属于a,一个属于b的情况,所以减去这部分情形
        ///即a中选一个,b中选一个,剩下的其他连通分支中选2个
        ///产生的贡献即为siz[a]*siz[b]*其他分支选两个
        ///其他分支计数,即(剩余的元素的个数的平方-其他分支的元素个数平方之和)/2
        tm-=(siz[a]*siz[a]+siz[b]*siz[b]);
        ll _=siz[a]*siz[b];
        siz[b]+=siz[a];
        ll o=n-siz[b];
        o=(o*o-tm)/2;
        _*=o;
        siz[a]=0;
        f[a]=b;
        K--;
        tm+=siz[b]*siz[b];
        return _;
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        init();
        K=n;
        ll _y=cal(n);
        cout<<_y<<'
    ';
        ll x,y,t;
        for(int i=0;i<m;i++){
            scanf("%lld%lld",&x,&y);
         
            if(K<4)cout<<0<<'
    ';
            else{
               ll t= uni(x,y);
                _y-=t;
                cout<<_y<<'
    ';
            }
        }
    
    }
  • 相关阅读:
    排队打饭 sdut 2443【最简单的贪心法应用举例】
    sdut 2445 小学数学
    最终排名 sdut 2446
    sort函数用法
    sdut1598 周游列国【简单模拟题】
    sdut 2441 屠夫与狼
    男生女生分配
    qsort函数详解
    test1.A[【dfs简单题】
    sdut 2449走迷宫【最简单的dfs应用】
  • 原文地址:https://www.cnblogs.com/liulex/p/11359678.html
Copyright © 2011-2022 走看看