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 , 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; }