1. 程式人生 > >bzoj 3159: 決戰【LCT】

bzoj 3159: 決戰【LCT】

urn UC string spa ace == i++ CP root

只是想復健一下LCT沒想到做了不得了的題……調了兩天QAQ
題解是這麽說的:
技術分享圖片
技術分享圖片
技術分享圖片
但是果然還不太理解……因為swap的前後問題調了好久,(所以一開始養成的習慣後面就不要再改啦……
總之大概就是把對位置lct的操作映射到權值lct上,然後權值lct可以隨便轉沒問題,只要位置lct不動就可以……
註意reverse!!

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=50005;
int n,q,root,h[N],cnt;
char c[20
]; struct qwe { int ne,to; }e[N<<1]; int read() { int r=0,f=1; char p=getchar(); while(p>‘9‘||p<‘0‘) { if(p==‘-‘) f=-1; p=getchar(); } while(p>=‘0‘&&p<=‘9‘) { r=r*10+p-48; p=getchar(); } return r*f; } void
add(int u,int v) { cnt++; e[cnt].ne=h[u]; e[cnt].to=v; h[u]=cnt; } struct val { int c[N][2],f[N],tg[N],si[N]; long long mn[N],mx[N],sum[N],va[N]; bool re[N]; void rev(int x) { swap(c[x][0],c[x][1]); re[x]^=1; } void init(int x,int v) { si[x]=1
; mn[x]=mx[x]=va[x]=sum[x]=v; } void add(int x,int v) {//////cerr<<x<<" "<<v<<endl; if(x) { sum[x]+=1ll*v*si[x]; tg[x]+=v; mn[x]+=v; mx[x]+=v; va[x]+=v; } } int fdrt(int x) {////cerr<<"fdrt"<<x<<endl; while(f[x]) x=f[x];//cerr<<x<<endl; return x; } void ud(int x) { si[x]=1,mn[x]=mx[x]=sum[x]=va[x]; if(c[x][0]) { si[x]+=si[c[x][0]]; mn[x]=min(mn[x],mn[c[x][0]]); mx[x]=max(mx[x],mx[c[x][0]]); sum[x]+=sum[c[x][0]]; } if(c[x][1]) { si[x]+=si[c[x][1]]; mn[x]=min(mn[x],mn[c[x][1]]); mx[x]=max(mx[x],mx[c[x][1]]); sum[x]+=sum[c[x][1]]; } } void pd(int x) { if(re[x]) { rev(c[x][0]); rev(c[x][1]); re[x]=0; } if(tg[x]) { add(c[x][0],tg[x]); add(c[x][1],tg[x]); tg[x]=0; } } int ppd(int x) { int anc=srt(x)?x:ppd(f[x]); pd(x); return anc; } bool srt(int x) { return c[f[x]][0]!=x&&c[f[x]][1]!=x; } void zhuan(int x) { int y=f[x],z=f[y],l=c[y][0]!=x,r=l^1; if(!srt(y)) c[z][c[z][0]!=y]=x; f[x]=z; c[y][l]=c[x][r]; f[c[x][r]]=y; c[x][r]=y; f[y]=x; ud(y); } void splay(int x) { ppd(x); while(!srt(x)) { int y=f[x],z=f[y]; if(!srt(y)) { if((c[y][0]==x)^(c[z][0]==y)) zhuan(x); else zhuan(y); } zhuan(x); } ud(x); } int zhao(int &x,int k) { while(1) { pd(x); if(k<=si[c[x][0]]) x=c[x][0]; else if(k==si[c[x][0]]+1) return x; else k-=(si[c[x][0]]+1),x=c[x][1]; } } }v; struct LCT { int si[N],c[N][2],f[N],rt[N]; bool re[N]; void rev(int x) { swap(c[x][0],c[x][1]); re[x]^=1; } void ud(int x) { si[x]=si[c[x][0]]+si[c[x][1]]+1; } void pd(int x) { if(re[x]) { rev(c[x][0]); rev(c[x][1]); re[x]=0; } } int ppd(int x) { int anc=srt(x)?x:ppd(f[x]); pd(x); return anc; } bool srt(int x) { return c[f[x]][0]!=x&&c[f[x]][1]!=x; } void zhuan(int x) { int y=f[x],z=f[y],l=c[y][0]!=x,r=l^1; if(!srt(y)) c[z][c[z][0]!=y]=x; f[x]=z; c[y][l]=c[x][r]; f[c[x][r]]=y; c[x][r]=y; f[y]=x; ud(y); } void splay(int x) { rt[x]=rt[ppd(x)]; while(!srt(x)) {////cerr<<x<<endl; int y=f[x],z=f[y]; if(!srt(y)) { if((c[y][0]==x)^(c[z][0]==y)) zhuan(x); else zhuan(y); } zhuan(x); } ud(x); } void acc(int x) {////cerr<<"ACC"<<endl; for(int y=0;x;y=x,x=f[x]) {//cerr<<x<<" "<<y<<endl; splay(x);//cerr<<"accoksplay"<<endl; int x2=v.fdrt(rt[x]),y2=v.fdrt(rt[y]);//cerr<<"accokflrt"<<endl; if(!y) y2=0; v.zhao(x2,si[c[x][0]]+1); v.splay(x2); rt[x]=x2; rt[c[x][1]]=v.c[x2][1]; v.f[v.c[x2][1]]=0; v.c[x2][1]=y2; v.f[y2]=x2; v.ud(x2); c[x][1]=y; ud(x); } } void mkrt(int x) { acc(x);//cerr<<"OKACC"<<endl; splay(x);//cerr<<"oksplay"<<endl; rev(x); v.rev(rt[x]); } void dfs(int u,int fa) { rt[u]=u,si[u]=1,f[u]=fa; v.init(u,0); for(int i=h[u];i;i=e[i].ne) if(e[i].to!=fa) dfs(e[i].to,u); } }w; int main() { n=read(),q=read(),root=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); add(x,y); add(y,x); } w.dfs(root,0); while(q--) { scanf("%s",c); int x=read(),y=read();//cerr<<"read"<<endl; w.mkrt(x);//cerr<<"mkrt"<<endl; w.acc(y);//cerr<<"acc"<<endl; int vy=v.fdrt(w.rt[y]); if(c[2]==‘c‘) { int z=read(); v.add(vy,z); } else if(c[2]==‘m‘) printf("%lld\n",v.sum[vy]); else if(c[2]==‘j‘) printf("%lld\n",v.mx[vy]); else if(c[2]==‘n‘) printf("%lld\n",v.mn[vy]); else v.rev(vy); } return 0; } /* 5 8 1 1 2 2 3 3 4 4 5 Sum 2 4 Increase 3 5 3 Minor 1 4 Sum 4 5 Invert 1 3 Major 1 2 Increase 1 5 2 Sum 1 5 */

bzoj 3159: 決戰【LCT】