BZOJ 2888: 资源运输
Description
加边,询问连通块中所有点到重心的距离。
Solution
LCT.
http://www.cnblogs.com/clrs97/p/4776809.html
一开始没想到怎么合并两颗树时候计算贡献...
Code
/************************************************************** Problem: 2888 User: BeiYu Language: C++ Result: Accepted Time:1560 ms Memory:6684 kb ****************************************************************/ #include <bits/stdc++.h> using namespace std; const int N = 100050; int n,q,ans; struct LinkCutTree { #define lc(o) ch[o][0] #define rc(o) ch[o][1] int f[N],ch[N][2]; int sz[N],s[N],a[N],d[N],t[N],tsz[N]; vector<int> g[N]; void AddEdge(int u,int v) { g[u].push_back(v),g[v].push_back(u); } void clr(int o) { sz[o]=tsz[o]=1,f[o]=lc(o)=rc(o)=s[o]=a[o]=d[o]=t[o]=0; } int isrt(int o) { return !f[o]||(lc(f[o])!=o&&rc(f[o])!=o); } void Tadd(int o,int _a) { if(!o) return; t[o]+=_a,tsz[o]+=_a; } void Tadd(int o,int _a,int _d) { if(!o) return; s[o]+=_a+sz[rc(o)]*_d,a[o]+=_a,d[o]+=_d; } void Push(int o) { if(t[o]) { Tadd(lc(o),t[o]),Tadd(rc(o),t[o]),t[o]=0; } if(d[o]) { Tadd(lc(o),a[o]+(sz[rc(o)]+1)*d[o],d[o]),Tadd(rc(o),a[o],d[o]),d[o]=a[o]=0; } } void Pushdown(int o) { if(!isrt(o)) Pushdown(f[o]);Push(o); } void Update(int o) { if(!o) return;sz[o]=sz[lc(o)]+sz[rc(o)]+1; } void Rot(int o) { int p=f[o],k=f[p],d=rc(p)==o; if(!isrt(p)) ch[k][rc(k)==p]=o; f[o]=k,f[p]=o,f[ch[o][d^1]]=p; ch[p][d]=ch[o][d^1],ch[o][d^1]=p; Update(p),Update(o),Update(k); } void Splay(int o) { Pushdown(o); for(;!isrt(o);) { int p=f[o],k=f[p]; if(!isrt(p)) Rot((rc(p)==o)==(rc(k)==p)?p:o); Rot(o); } } void Access(int o) { for(int v=0;o;o=f[v=o]) Splay(o),rc(o)=v,Update(o); } int Getrt(int o) { Access(o),Splay(o);for(;lc(o);o=lc(o));return o; } void Addp(int u,int v) { clr(v),f[v]=u,tsz[v]=0; u=Getrt(u),Access(v),Splay(u),Tadd(u,1),Tadd(u,0,1); for(v=rc(u);lc(v);v=lc(v));Splay(v); if(2*tsz[v]>tsz[u]) { int su=tsz[u],sv=tsz[v]; tsz[v]=su,tsz[u]-=sv; s[u]-=s[v]+sv,s[v]+=s[u]+su-sv; Access(v),Splay(u),lc(u)=v,rc(u)=0; } } void DFS(int u,int fa) { Addp(fa,u); for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa) DFS(v,u); } void Link(int u,int v) { int ru=Getrt(u),rv=Getrt(v); ans-=s[ru]+s[rv]; if(tsz[ru]<tsz[rv]) swap(u,v); DFS(v,u),AddEdge(u,v); ans+=s[Getrt(u)]; } void init() { for(int i=1;i<=n;i++) clr(i); } }py; int main() { // freopen("in.in","r",stdin); scanf("%d%d",&n,&q); py.init(); for(int i=1;i<=q;i++) { char opt[5];int x,y; scanf("%s",opt); if(*opt=='A') scanf("%d%d",&x,&y),py.Link(x,y); else printf("%d\n",ans); // printf("%d\n",ans); }return 0; }