1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include <bits/stdc++.h> using namespace std; #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) #define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++) #define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--) #define DEBUG(x) cout<<#x<<"="<<x<<endl; #define all(x) (x).begin(),(x).end() #define cle(x) memset(x,0,sizeof(x)) #define ll long long #define ull unsigned ll #define db double #define lb long db #define pb push_back #define mp make_pair #define pii pair<int,int> #define fi first #define se second inline int read() { int x=0; char ch=getchar(); bool f=0; for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1; for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48); return f?-x:x; } #define CASET fo(___,1,read()) const int N=100010; int fa[N],siz[N]; int n; ll ans; unordered_set<int> v[N],g[N],t[N],s[N]; int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} inline ll calc(int x) { return 1ll*siz[x]*(siz[x]-1+v[x].size()); } inline void merge(int x,int y) { ans-=calc(x)+calc(y); if(siz[x]+v[x].size()<siz[y]+v[y].size()) swap(x,y); vector<int> q; for(auto u:t[y]) if(t[u].count(x)) q.pb(u); for(auto u:g[y]) if(g[u].count(x)) q.pb(u);
g[x].erase(y); g[y].erase(x); t[x].erase(y); t[y].erase(x); for(auto u:t[y]) t[x].insert(u),g[u].erase(y),g[u].insert(x); for(auto u:g[y]) g[x].insert(u),t[u].erase(y),t[u].insert(x); for(auto u:v[y]) if(find(u)!=x) v[x].insert(u); for(auto u:s[y]) if(v[x].count(u)) v[x].erase(u); for(auto u:s[y]) s[x].insert(u);
siz[x]+=siz[y]; fa[y]=x; ans+=calc(x);
for(auto u:q) if(find(u)!=find(x)) merge(find(u),find(x)); } inline void update(int x,int y) { int fx=find(x),fy=find(y); if(fx==fy) return; if(!v[fy].count(x)) v[fy].insert(x),ans+=siz[fy]; if(t[fx].count(fy)) return;
if(!t[fy].count(fx)) t[fx].insert(fy),g[fy].insert(fx); else merge(fx,fy); } int main() { n=read(); fo(i,1,n) fa[i]=i,siz[i]=1,s[i].insert(i); int x,y; CASET { x=read(),y=read(); update(x,y); printf("%lld\n",ans); } return 0; }
|