1036: [ZJOI2008]树的统计Count

来源:互联网 发布:补偿网络 编辑:程序博客网 时间:2024/06/01 14:55
链剖

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

 

0 0
原创粉丝点击