首页 > 代码库 > BZOJ 2888: 资源运输

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

  

BZOJ 2888: 资源运输