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