1036: [ZJOI2008]树的统计Count
链剖
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 #define INF 1000000000 7 #define N 30000*4 8 int n,m,cnt,num[N],fa[N],sum[N],mmax[N],size[N],depth[N],at[N],son[N],head[N]; 9 int tot,g[N],nnext[N],v[N]; 10 void Add(int x,int y){tot++;nnext[tot]=g[x];g[x]=tot;v[tot]=y;} 11 void Dfs(int x) 12 { 13 int max_size=0;size[x]=1; 14 for(int i=g[x];i;i=nnext[i]) 15 { 16 int tmp=v[i]; 17 if(tmp!=fa[x]) 18 { 19 fa[tmp]=x; 20 depth[tmp]=depth[x]+1; 21 Dfs(tmp); 22 size[x]+=size[tmp]; 23 if(size[tmp]>size[max_size]) max_size=tmp; 24 } 25 } 26 son[x]=max_size; 27 } 28 void Build(int x,int top) 29 { 30 at[x]=++cnt; 31 head[x]=top; 32 if(son[x]!=0) Build(son[x],top); 33 for(int i=g[x];i;i=nnext[i]) 34 { 35 int tmp=v[i]; 36 if(tmp!=fa[x]&&tmp!=son[x]) 37 { 38 Build(tmp,tmp); 39 } 40 } 41 } 42 void Up(int x) 43 { 44 sum[x]=sum[x*2]+sum[x*2+1]; 45 mmax[x]=max(mmax[x*2+1],mmax[x*2]); 46 } 47 void Change(int now,int L,int R,int loc,int x) 48 { 49 if(L==R) {num[L]=x;sum[now]=x;mmax[now]=x;return ;} 50 int mid=(L+R)/2; 51 if(loc<=mid) Change(now*2,L,mid,loc,x); 52 else Change(now*2+1,mid+1,R,loc,x); 53 Up(now); 54 } 55 int ans_mmax=-INF,ans_sum=0; 56 void F(int now,int L,int R,int s,int t) 57 { 58 if(s<=L&&t>=R) 59 { 60 ans_mmax=max(ans_mmax,mmax[now]); 61 ans_sum+=sum[now];return ; 62 } 63 int mid=(L+R)/2; 64 if(s<=mid) F(now*2,L,mid,s,t); 65 if(mid+1<=t) F(now*2+1,mid+1,R,s,t); 66 } 67 void Lca(int x,int y) 68 { 69 while(head[x]!=head[y]) 70 { 71 if(depth[head[x]]<depth[head[y]]) swap(x,y); 72 F(1,1,n,at[head[x]],at[x]); 73 x=fa[head[x]]; 74 } 75 if(!x)return ; 76 if(depth[x]<depth[y]) swap(x,y); 77 F(1,1,n,at[y],at[x]); 78 } 79 int main() 80 { 81 cin>>n;int x,y; 82 for(int i=1;i<n;i++) scanf("%d %d",&x,&y),Add(x,y),Add(y,x); 83 Dfs(1);Build(1,1); 84 for(int i=1;i<=n;i++) scanf("%d",&x),Change(1,1,n,at[i],x); 85 char s[100]; 86 cin>>m; 87 while(m--) 88 { 89 scanf("%s %d %d",s+1,&x,&y); 90 switch(s[2]) 91 { 92 case 'M':ans_mmax=-INF;Lca(x,y);printf("%d\n",ans_mmax);break; 93 case 'H':Change(1,1,n,at[x],y);break; 94 case 'S':ans_sum=0;Lca(x,y);printf("%d\n",ans_sum);break; 95 } 96 } 97 return 0; 98 }
LCT to[N][0] 233333
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 #define N 30000+10 7 #define INF 1000000000 8 #define L(x) to[x][0] 9 #define R(x) to[x][1] 10 int n,m,fa[N],to[N][2],num[N],mmax[N],sum[N]; 11 bool mark[N]; 12 void Up(int x) 13 { 14 sum[x]=sum[L(x)]+sum[R(x)]+num[x]; 15 mmax[x]=max(num[x],max(mmax[L(x)],mmax[R(x)])); 16 } 17 void Pushdown(int x) 18 { 19 if(!mark[x])return ; 20 mark[x]=false; 21 swap(L(x),R(x)); 22 mark[L(x)]^=1; 23 mark[R(x)]^=1; 24 } 25 bool Is(int x) 26 { 27 return L(fa[x])!=x&&R(fa[x])!=x; 28 }bool ok=false; 29 void Rotate(int x) 30 { 31 int y=fa[x],z=fa[y]; 32 Pushdown(y);Pushdown(x); 33 if(!Is(y)) to[z][to[z][1]==y]=x; 34 int c=to[y][1]==x; 35 fa[x]=z;fa[y]=x;fa[to[x][c^1]]=y; 36 to[y][c]=to[x][c^1];to[x][c^1]=y; 37 Up(y);Up(x); 38 } 39 void Splay(int x) 40 { 41 42 Pushdown(x); 43 while(!Is(x)) 44 { 45 if(!Is(fa[x])) Rotate(fa[x]); 46 Rotate(x); 47 } 48 } 49 void Access(int x) 50 { 51 int t=0; 52 while(x) 53 { 54 Splay(x); 55 R(x)=t; 56 t=x;Up(x); 57 58 x=fa[x]; 59 } 60 } 61 void Markroot(int x) 62 { 63 Access(x);Splay(x);mark[x]^=1; 64 } 65 void Change(int x,int y) 66 { 67 Splay(x);num[x]=y;Up(x); 68 } 69 void Link(int x,int y) 70 { 71 Markroot(x);fa[x]=y; 72 } 73 int F(int x,int y) 74 { 75 Markroot(x);Pushdown(x);Access(y);Splay(y);R(y)=0;Up(y); 76 return y; 77 } 78 int main() 79 { 80 cin>>n;int x,y;mmax[0]=-INF; 81 for(int i=1;i<n;i++) scanf("%d %d",&x,&y),Link(x,y); 82 for(int i=1;i<=n;i++) scanf("%d",&x),Change(i,x); 83 cin>>m; 84 char s[100]; 85 while(m--) 86 { 87 scanf("%s %d %d",s+1,&x,&y); 88 switch(s[2]) 89 { 90 case 'H':Change(x,y);break; 91 case 'M':printf("%d\n",mmax[F(x,y)]);break; 92 case 'S':printf("%d\n",sum[F(x,y)]);break; 93 } 94 } 95 return 0; 96 }