Obviously the resource collection is the center of the tree, which requires dynamic maintenance of the tree's center of gravity.
Each connected block is centered on the center of gravity, with the link-cut tree maintaining the subtree size of each point and the distance from all points within the subtree to it.
When merging two connected blocks, consider heuristic merging and violence to add leaves to large trees.
When adding leaves, you need to add the leaves to the subtree size of all points on the center of Gravity Path by +1, and a arithmetic progression to the distance.
and the new center of gravity is probably the original center of gravity or the original center of gravity to the first point on the leaf path, violence can be.
Time complexity $o (N\LOG^2N) $.
#include <cstdio> #define N 40010int N,m,i,x,y,ans;char op[5];int G[n],v[n<<1],nxt[n<<1],ed,f[n], son[n][2],val[n],tag[n],sum[n],ts[n],td[n],size[n],tmp[n];inline void Swap (int&a,int&b) {int c=a;a=b;b=c;} inline bool IsRoot (int x) {return!f[x]| | Son[f[x]][0]!=x&&son[f[x]][1]!=x;} inline void add1 (int x,int p) {if (!x) return;val[x]+=p;tag[x]+=p;} inline void add2 (int x,int s,int d) {if (!x) Return;sum[x]+=s+size[son[x][1]]*d;ts[x]+=s;td[x]+=d;} inline void pb (int x) {if (tag[x]) {add1 (son[x][0],tag[x]); ADD1 (Son[x][1],tag[x]); tag[x]=0; } if (Td[x]) {add2 (son[x][0],ts[x]+ (size[son[x][1]]+1) *td[x],td[x]); ADD2 (Son[x][1],ts[x],td[x]); ts[x]=td[x]=0; }}inline void up (int x) {size[x]=size[son[x][0]]+size[son[x][1]]+1;} inline void rotate (int x) {int y=f[x],w=son[y][1]==x; SON[Y][W]=SON[X][W^1]; if (son[x][w^1]) f[son[x][w^1]]=y; if (F[y]) {int z=f[y]; if (son[z][0]==y) Son[z][0]=x;else if (son[z][1]==y) son[z][1]=x; } f[x]=f[y];f[y]=x;son[x][w^1]=y; Up (y);} inline void splay (int x) {int s=1,i=x,y;tmp[1]=i; while (!isroot (i)) tmp[++s]=i=f[i]; while (s) PB (tmp[s--]); while (!isroot (x)) {y=f[x]; if (!isroot (y)) {if ((son[f[y]][0]==y) ^ (son[y][0]==x)) rotate (x); else rotate (y);} Rotate (x); } up (x);} inline void access (int x) {for (int y=0;x;y=x,x=f[x]) splay (x), Son[x][1]=y,up (x);} inline int root (int x) {access (x); splay (x); while (son[x][0]) X=son[x][0];return x;} inline void addleaf (int x,int y) {f[y]=x,son[y][0]=son[y][1]=val[y]=tag[y]=sum[y]=ts[y]=td[y]=0,size[y]=1; X=root (x), Access (y), splay (x), Add1 (x,1), ADD2 (x,0,1); for (Y=son[x][1];son[y][0];y=son[y][0]); splay (y); int vx=val[x],vy=val[y]; if (VY*2>VX) {val[y]=vx,val[x]-=vy; Sum[x]-=sum[y]+vy,sum[y]+=sum[x]+vx-vy; Access (y), splay (x), son[x][0]=y,son[x][1]=0; }}void dfs (int x,int y) {addleaf (y,x); for (int i=g[x];i;i=nxt[i]) if (v[i]!=y) DFS (v[i],x);} inline void Addedge (int x,int y) {v[++ed]=y;nxt[ed]=g[x];g[x]=ed;} inline void link (int x,int y) {int x=root (x), Y=root (y); Ans-=sum[x]+sum[y]; if (Val[x]<val[y]) swap (x, y); DFS (Y,X), Addedge (x, y), Addedge (y,x); Ans+=sum[root (x)];} int main () {scanf ("%d%d", &n,&m); for (i=1;i<=n;i++) val[i]=size[i]=1; while (m--) {scanf ("%s", op); if (op[0]== ' A ') scanf ("%d%d", &x,&y), link (x, y); if (op[0]== ' Q ') printf ("%d\n", ans); } return 0;}
BZOJ2888: Resource Transport