9th E-All men are brothers (disjoint-set)

The meaning of problems : n individual, m operations, each operation such that the two (x, y) become friends, friend relationship can be transmitted, calculation is performed after each operation to select four different schemes are not twenty-two friend Number of.

Data range: (n-<= 100000, m <= 200000) (. 1 <= X <= n-,. 1 <= Y <= n-, X ≠ Y)

Input requirements:

The first line contains two integers, n and m

In the following m-th row, the i-th row comprising two integers x and y, which means that the x and y individual person in the first round dating.

The first x and y personal individuals may make friends in several rounds.

Output requirements:

M + 1 output lines, each comprising an integer, i.e., 4 to select the number of individual programs.

Operation before and after each round output, therefore m + 1 rows.

Ideas:

We are all friends into a set of x where x is a collection of collections, a collection of empathy y, z other unified collection (there are several disjoint-set). If the x, y a set of the same, for the (x + y) set .

If the x, y not in the same set, a total of x1 + z3 (x 1 selected from inside, z which is selected from 3), y1 + z3, x1 + y1 + z2, z4, these four cases,

And x, y after the merger, a total of z4, (x + y) 1 + z3 [equivalent to x1 + z3, y1 + z3], so if you need to merge, minus x1 + y1 + z2 this situation can be.

Calculation:

Initially everyone the answer is not friends with each other  \textrm{C}_{n}^{4} , due to the relatively large n, the need to use  unsigned Long Long;

It began after the merger:

If the x, y not in the same set, if desired combined, x1 + y1 + z2 subtracting this case,

I.e. A * B * ((NAB) * (NAB) -s + A * A + B * B) / 2 (A represents the x-number set, b represents the number of y set, s start total number is updated to S + = 2 * a * b), involved here combinatorics .

When the same set of output on an answer.

Code:

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N=1e5+10;
int f[N],c[N];
ll Find(int x)
{
    return f[x]==x?x:f[x]=Find(f[x]);
}
int main()
{
    ios::sync_with_stdio(0);
    for(int i=0;i<N;i++)
        f[i]=i,c[i]=1;
    ll n; int m; cin>>n>>m;
    ll ans=n*(n-1)/2*(n-2)/3*(n-3)/4,s=n;
    while(m--){
        cout<<ans<<endl;
        int u,v; cin>>u>>v;
        u=Find(u); v=Find(v);
        if(u==v||ans==0) continue;
        ll a=c[u],b=c[v];
        ans-=a*b*((n-a-b)*(n-a-b)-s+a*a+b*b)/2;
        s+=2*a*b;
        c[v]+=c[u];
        f[u]=v;
    }
    cout<<ans<<endl;
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/young-children/p/11366603.html