牛客多校第九场 E All men are brothers 并查集/组合论

题意:

一开始有n人互不认识,每回合有两个人认识,认识具有传递性,也就是相互认识的人组成小团体。现在问你每个回合,挑选四个人,这四个人互不认识,有多少种挑选方法。

题解:

认识不认识用并查集维护即可,重点在于如何统计挑选方法。

每个回合两个人互相认识,排除两个人本就在一个小团体中的情况,实际上就是两个小团体结合为一个。

那么变得无效化的挑选方法,实际上就是两个人分别来自这两个小团体,剩下两个人来自其他小团体的情况。

从其他集合的所有元素先任取两个,再去掉来自同一集合的两个的情况。

减少的数量等于合并的两个集合大小乘以以上结果。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef long long ll;
typedef pair<int, LL>P;
const int M = 4e5 * 4 + 5;
const LL mod = 1e9 + 7;
const LL lINF = 0x3f3f3f3f3f3f3f3f;
#define ls (rt<<1)
#define rs (rt<<1|1)
int n, fa[M], ra[M], m;
uLL num[M];
void init(int n)
{
    for (int i = 1; i <= n; i++)
    {
        fa[i] = i;
        ra[i] = 1;
        num[i] = 1;
    }
}
int find(int x)
{
    if (fa[x] == x)
        return x;
    else
        return fa[x] = find(fa[x]);
}
void unite(int x, int y)
{
    x = find(x);
    y = find(y);
    if (ra[x] < ra[y])
    {
        fa[x] = y;
        num[y] += num[x];
    }
    else
    {
        fa[y] = x;
        num[x] += num[y];
        if (ra[x] == ra[y])
            ra[x]++;
    }
}
uLL ans;
uLL sum;
int l, r;
int main()
{
    scanf("%d%d", &n, &m);
    ans = (uLL)n *(n - 1)*(n - 2)/6*(n - 3)/4;
    cout<<ans<<endl;
    sum = 0;
    init(n);
    while (m--)
    {
        scanf("%d%d", &l, &r);
        l = find(l);
        r = find(r);
        if (l == r)
        {
           cout<<ans<<endl;
            continue;
        }
        else
        {
            uLL lst = n - num[l] - num[r];
            uLL tmp;
            tmp = lst * (lst - 1) / 2;
            tmp = tmp - sum + num[l] * (num[l] - 1) / 2 + num[r] * (num[r] - 1) / 2;
            tmp = tmp * num[l] * num[r];
            ans -= tmp;
            cout<<ans<<endl;
            tmp = num[l] * (num[l] - 1) / 2 + num[r] * (num[r] - 1) / 2;
            sum -= tmp;
            unite(l, r);
            l = find(l);
//            r = find(r);
//            assert(l==r);
            sum += num[l] * (num[l] - 1) / 2;
        }
    }
}

 

posted @ 2019-08-15 23:40  Isakovsky  阅读(231)  评论(0编辑  收藏  举报