The meaning of problems
N-$ $ initially and do not know each individual, then $ m $ rows, each row having $ x, y $, $ represents $ Y $ and X $ friends, friends satisfies transitivity and reflexivity, each selecting the number of output current and four individuals did not know each program.
analysis
Disjoint-set and maintain the collection.
And to consider the impact of two sets of answers, the whole is minus a selected set of x, y select a collection, choose the remaining two (two from different collections).
Understand the role of $ cs $ variable on the code.
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; const int maxn = 1e5 + 10; int n, m; int fa[maxn], rk[maxn]; ll C4(ll x) { return x * (x-1)/2 * (x-2)/3 * (x-3)/4; } ll C2(ll x) { return x * (x-1) / 2; } void init() { for(int i = 1;i <= n;i++) { fa[i] = i; rk[i] = 1; } } int find(int x) { if(x != fa[x]) fa[x] = find(fa[x]); return fa[x]; } void unite(int x, int y) { int rx = find(x); int ry = find(y); if(rx == ry) return; fa[rx] =Ry; RK [Ry] + = RK [RX]; } int main () { Scanf ( " % D% D " , & n-, & m); LL ANS = C4 (n-); the printf ( " % LLD \ n- " , ANS); the init (); LL CS = 0 ; // each set of two access schemes and for ( int I = 0 ; I <m; I ++ ) { int a, B; Scanf ( " % % D D " , A &, & B); IF(find(a) == find(b)) { printf("%lld\n", ans); continue; } int rka = rk[find(a)], rkb = rk[find(b)]; ll tmp1 = 1LL * rka * rkb; ll tmp2 = C2(n-rka-rkb) - (cs - (C2(rka)+C2(rkb))); cs = cs - (C2(rka)+C2(rkb)) + C2(rka+rkb); ans -= tmp1 * tmp2; printf("%lld\n", ans); unite(a, b); } return 0; }