[BZOJ3779]重组病毒(LCT+DFS序线段树)
同[BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define lc ch[x][0] 4 #define rc ch[x][1] 5 #define ls (x<<1) 6 #define rs (ls|1) 7 #define lson ls,L,mid 8 #define rson rs,mid+1,R 9 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i]) 11 typedef long long ll; 12 using namespace std; 13 14 const int N=100010; 15 char op[10]; 16 ll tag[N<<2],sm[N<<2]; 17 int n,m,u,v,x,rt,cnt,tim,rev[N],h[N],nxt[N<<1],to[N<<1]; 18 int L[N],R[N],dep[N],fa[N][20],ch[N][2],sz[N],f[N]; 19 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 20 21 inline int rd(){ 22 int x=0; char ch=getchar(); bool f=0; 23 while (ch<'0' || ch>'9') f|=ch=='-',ch=getchar(); 24 while (ch>='0' && ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); 25 return f ? -x : x; 26 } 27 28 int jump(int x,int k){ 29 for (int i=18; ~i; i--) if (k&(1<<i)) x=fa[x][i]; return x; 30 } 31 32 void push(int x,int L,int R){ 33 if (!tag[x]) return; 34 int mid=(L+R)>>1; 35 sm[ls]+=tag[x]*(mid-L+1); tag[ls]+=tag[x]; 36 sm[rs]+=tag[x]*(R-mid); tag[rs]+=tag[x]; 37 tag[x]=0; 38 } 39 40 void mdf(int x,int L,int R,int l,int r,int k){ 41 if (L==l && r==R){ sm[x]+=1ll*k*(R-L+1); tag[x]+=k; return; } 42 int mid=(L+R)>>1; push(x,L,R); 43 if (r<=mid) mdf(lson,l,r,k); 44 else if (l>mid) mdf(rson,l,r,k); 45 else mdf(lson,l,mid,k),mdf(rson,mid+1,r,k); 46 sm[x]=sm[ls]+sm[rs]; 47 } 48 49 ll que(int x,int L,int R,int l,int r){ 50 if (L==l && r==R) return sm[x]; 51 int mid=(L+R)>>1; push(x,L,R); 52 if (r<=mid) return que(lson,l,r); 53 else if (l>mid) return que(rson,l,r); 54 else return que(lson,l,mid)+que(rson,mid+1,r); 55 } 56 57 void dfs(int x){ 58 L[x]=++tim; dep[x]=dep[fa[x][0]]+1; sz[x]=1; 59 rep(i,1,18) fa[x][i]=fa[fa[x][i-1]][i-1]; 60 mdf(1,1,n,L[x],L[x],dep[x]); 61 For(i,x) if ((k=to[i])!=fa[x][0]) fa[k][0]=x,f[k]=x,dfs(k),sz[x]+=sz[k]; 62 R[x]=tim; 63 } 64 65 bool isrt(int x){ return (!f[x]) || (ch[f[x]][0]!=x && ch[f[x]][1]!=x); } 66 void put(int x){ swap(lc,rc); rev[x]^=1; } 67 void push(int x){ if (rev[x]) put(lc),put(rc),rev[x]=0; } 68 void pd(int x){ if (!isrt(x)) pd(f[x]); push(x); } 69 70 void rot(int x){ 71 int y=f[x],z=f[y],w=ch[y][1]==x; 72 if (!isrt(y)) ch[z][ch[z][1]==y]=x; 73 f[x]=z; f[y]=x; f[ch[x][w^1]]=y; 74 ch[y][w]=ch[x][w^1]; ch[x][w^1]=y; 75 } 76 77 void splay(int x){ 78 pd(x); 79 while (!isrt(x)){ 80 int y=f[x],z=f[y]; 81 if (!isrt(y)) (ch[z][1]==y)^(ch[y][1]==x) ? rot(x) : rot(y); 82 rot(x); 83 } 84 } 85 86 void work(int x,int k){ 87 if (rt==x) mdf(1,1,n,1,n,k); 88 else if (L[rt]>=L[x] && L[rt]<=R[x]){ 89 int t=jump(rt,dep[rt]-dep[x]-1); 90 if (L[t]>1) mdf(1,1,n,1,L[t]-1,k); 91 if (R[t]<n) mdf(1,1,n,R[t]+1,n,k); 92 }else mdf(1,1,n,L[x],R[x],k); 93 } 94 95 int find(int x){ 96 push(x); 97 while (lc) x=lc,push(x); 98 return x; 99 } 100 101 void access(int x){ 102 for (int y=0; x; y=x,x=f[x]){ 103 splay(x); 104 if (rc) work(find(rc),1); 105 if (y) work(find(y),-1); 106 rc=y; 107 } 108 } 109 110 void mkrt(int x){ access(x); splay(x); put(x); } 111 112 int main(){ 113 freopen("bzoj3779.in","r",stdin); 114 freopen("bzoj3779.out","w",stdout); 115 n=rd(); m=rd(); 116 rep(i,2,n) u=rd(),v=rd(),add(u,v),add(v,u); 117 dfs(1); rt=1; 118 while (m--){ 119 scanf("%s",op); x=rd(); 120 if (op[2]=='L') access(x); 121 if (op[2]=='C') mkrt(x),rt=x; 122 if (op[2]=='Q'){ 123 if (rt==x) printf("%.10lf\n",1.*que(1,1,n,1,n)/n); 124 else if (L[rt]>=L[x] && L[rt]<=R[x]){ 125 int t=jump(rt,dep[rt]-dep[x]-1); 126 ll res1=L[t]>1 ? que(1,1,n,1,L[t]-1) : 0; 127 ll res2=R[t]<n ? que(1,1,n,R[t]+1,n) : 0; 128 printf("%.10lf\n",1.*(res1+res2)/(n-sz[t])); 129 }else printf("%.10lf\n",1.*que(1,1,n,L[x],R[x])/sz[x]); 130 } 131 } 132 return 0; 133 }