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

 

posted @ 2016-02-25 11:32  sxb_201  阅读(159)  评论(0编辑  收藏  举报