1036: [ZJOI2008]树的统计Count

树链剖分 模板题:

   和线段树一起写各种bug:

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<math.h>
  4 #include<vector>
  5 #include<string.h>
  6 #include<string>
  7 #include<set>
  8 #include<iostream>
  9 using namespace std;
 10 typedef long long ll;
 11 #define N 33333
 12 
 13 int head[N],top[N],fa[N],tot;
 14 
 15 int son[N],p[N],fp[N],dep[N],pos;
 16 int sz[N];
 17 
 18 void init()
 19 {
 20     tot=0;
 21     memset(head,-1,sizeof(head));
 22     memset(son,-1,sizeof(son));
 23     pos=0;
 24 }
 25 
 26 struct node
 27 {
 28     int v,next;
 29 }e[N<<1];
 30 
 31 void add(int u,int v)
 32 {
 33     e[tot].v=v;
 34     e[tot].next=head[u];
 35     head[u]=tot++;
 36 }
 37 
 38 void dfs(int u,int f,int d)
 39 {
 40     dep[u]=d;
 41     fa[u]=f;
 42     sz[u]=1;
 43 
 44     for (int i=head[u];i!=-1;i=e[i].next)
 45     {
 46         int v=e[i].v;
 47         if (v==f) continue;
 48         dfs(v,u,d+1);
 49         sz[u]+=sz[v];
 50         if (son[u]==1||sz[son[u]]<sz[v]) son[u]=v;
 51     }
 52 }
 53 
 54 void getpos(int u,int sp)
 55 {
 56     top[u]=sp;
 57     p[u]=++pos;
 58     fp[pos]=u;
 59     if (son[u]==-1) return;
 60     getpos(son[u],sp);
 61     for (int i=head[u];i!=-1;i=e[i].next)
 62     {
 63        int v=e[i].v;
 64        if (v!=son[u]&&v!=fa[u])
 65        getpos(v,v);
 66     }
 67 }
 68 
 69 struct node2
 70 {
 71     int l,r,Max,sum;
 72 }tree[N<<2];
 73 
 74 
 75 void pushup(int rt)
 76 {
 77     tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max);
 78     tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
 79 }
 80 
 81 
 82 void build(int l,int r,int rt)
 83 {
 84     tree[rt].l=l;
 85     tree[rt].r=r;
 86     tree[rt].Max=tree[rt].sum=0;
 87 
 88     if (l==r) return ;
 89     int m=(l+r)>>1;
 90     build(l,m,rt<<1);
 91     build(m+1,r,rt<<1|1);
 92 }
 93 
 94 void update(int pos,int x,int l,int r,int rt)
 95 {
 96     if (l==r)
 97     {
 98         tree[rt].Max=tree[rt].sum=x;
 99         return;
100     }
101     int m=(l+r)>>1;
102     if (pos<=m) update(pos,x,l,m,rt<<1);
103     else update(pos,x,m+1,r,rt<<1|1);
104     pushup(rt);
105 }
106 
107 int  querymax(int l,int r,int rt)
108 {
109   if (tree[rt].l>=l&&tree[rt].r<=r)
110       return tree[rt].Max;
111   int m=(tree[rt].l+tree[rt].r)>>1;
112 
113   if (r<=m) return querymax(l,r,rt<<1);
114   else if (l>m) return querymax(l,r,rt<<1|1);
115   else return max(querymax(l,m,rt<<1),querymax(m+1,r,rt<<1|1));
116 }
117 
118 
119 int  querysum(int l,int r,int rt)
120 {
121   if (tree[rt].l>=l&&tree[rt].r<=r)
122       return tree[rt].sum;
123 
124   int m=(tree[rt].l+tree[rt].r)>>1;
125   if (r<=m) return querysum(l,r,rt<<1);
126   else if (l>m) return querysum(l,r,rt<<1|1);
127   else return querysum(l,m,rt<<1)+querysum(m+1,r,rt<<1|1);
128 }
129 
130 int Sum,Max;
131 
132 void  lca(int u,int v)
133 {
134     int fu=top[u];
135     int fv=top[v];
136     Sum=0;
137     Max=-24242554;
138     while (fu!=fv)
139     {
140         if (dep[fu]<dep[fv])
141         {
142             swap(fu,fv);
143             swap(u,v);
144         }
145 
146         Max=max(Max,querymax(p[fu],p[u],1));
147         Sum+=querysum(p[fu],p[u],1);
148         u=fa[fu];
149         fu=top[u];
150     }
151     
152     if (dep[u]>dep[v]) swap(u,v);
153     Max=max(Max,querymax(p[u],p[v],1));
154     Sum+=querysum(p[u],p[v],1);
155     
156     //Max=max(Max,querymax(p[fa[u]],p[v],1));
157     //Sum+=querysum(p[fa[u]],p[v],1);
158 }
159 int a[N];
160 
161 int main()
162 {
163     int n;
164     scanf("%d",&n);
165     init();
166     for (int i=1;i<n;i++)
167     {
168         int x,y;
169         scanf("%d%d",&x,&y);
170         add(x,y);
171         add(y,x);
172     }
173     dfs(1,0,0);
174     getpos(1,1);
175     build(1,pos,1);
176 
177     for (int i=1;i<=n;i++) scanf("%d",&a[i]),update(p[i],a[i],1,pos,1);
178 
179     int Q;
180     scanf("%d",&Q);
181     while (Q--)
182     {
183       char s[10];
184       int x,y;
185       scanf("%s",s);
186       scanf("%d%d",&x,&y);
187       if (s[0]=='C') update(p[x],y,1,pos,1);
188       else
189       {
190           lca(x,y);
191           if (s[1]=='M') printf("%d\n",Max);
192           else printf("%d\n",Sum);
193       }
194     }
195 
196     return 0;
197 }

 

posted on 2015-07-03 20:11  forgot93  阅读(161)  评论(0编辑  收藏  举报

导航