Cattle off more school ninth field E All men are brothers disjoint-set / combinatorics

Meaning of the questions:

At first there were n people do not know each other, know each round there are two people, know transitive, that is, people know each composed of small groups. Now you ask each round, the selection of four people, four men and do not know how many kinds of selection methods.

answer:

Know do not know with disjoint-set to maintain a focus on how the statistical selection methods.

Each round of two people know each other, this would exclude two people in a small group of cases, actually two small groups combined into one.

It becomes ineffective method of selection, in fact, two people from each of these two small groups, two people from the rest of other small groups.

All other elements from any of the first set to take two, then remove the case from the same set of two.

Reduced number equal to the combined result of two or more multiply the amount set.

#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 = lf * (ls - 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 ) / 2Surely + [R] * (whether [R] - 1 ) / 2 ; 
            I - = tmp; 
            unitedly (L, R); 
            l = find (l);
//             r = find (R);
//             assert (l == R); 
            sum + = num [i] * (num [i] - 1 ) / 2 ; 
        } 
    } 
}

 

Guess you like

Origin www.cnblogs.com/isakovsky/p/11361280.html