HYSBZ1036-树链剖分-点权

树链剖分,点权,单点更改,路径查询。学树链剖分下面这个博文不错

http://blog.csdn.net/y990041769/article/details/40348013

线段树必须写的很熟练才行。注意负数

  1 #include <cstdio>
  2 #include <vector>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 
  7 const int maxn = 3e4+10;
  8 const int INF = 0x3f3f3f3f;
  9 
 10 /////////////////////////////////////
 11 int topw;
 12 int son[maxn],top[maxn],fa[maxn],siz[maxn],id[maxn],dep[maxn];
 13 int val[maxn],pre_val[maxn];
 14 
 15 vector<int> G[maxn];
 16 
 17 void dfs_1(int u,int f,int d)
 18 {
 19     son[u] = 0;
 20     dep[u] = d;
 21     fa[u]  = f;
 22     siz[u] = 1;
 23     for(int i=0;i<G[u].size();i++)
 24     {
 25         int v = G[u][i];
 26         if(v == f) continue;
 27         dfs_1(v,u,d+1);
 28         siz[u] += siz[v];
 29         if(siz[son[u]] < siz[v])
 30         {
 31             son[u] = v;
 32         }
 33     }
 34 }
 35 
 36 void dfs_2(int u,int tp)
 37 {
 38     top[u] = tp;
 39     id[u] = ++topw;
 40     if(son[u]) dfs_2(son[u],tp);
 41     for(int i=0;i<G[u].size();i++)
 42     {
 43         int v = G[u][i];
 44         if(v == fa[u] || v == son[u]) continue;
 45         dfs_2(v,v);
 46     }
 47 }
 48 
 49 ////////////////////////////////////
 50 #define lson l,m,rt<<1
 51 #define rson m+1,r,rt<<1|1
 52 #define root 1,topw,1
 53 
 54 int sum[maxn<<2];
 55 int mx[maxn<<2];
 56 
 57 void push_up(int rt)
 58 {
 59     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
 60     mx[rt] = max(mx[rt<<1],mx[rt<<1|1]);
 61 }
 62 
 63 void build(int l,int r,int rt)
 64 {
 65     sum[rt] = 0;
 66     mx[rt] = 0;
 67     if(l == r)
 68     {
 69         sum[rt] = val[l];
 70         mx[rt] = val[l];
 71         return ;
 72     }
 73     int m = (l+r)>>1;
 74     build(lson);
 75     build(rson);
 76     push_up(rt);
 77 }
 78 
 79 void update(int pos,int add,int l,int r,int rt)
 80 {
 81     if(l == r)
 82     {
 83         sum[rt] = add;
 84         mx[rt] = add;
 85         return ;
 86     }
 87     int m = (l+r)>>1;
 88     if(pos <= m) update(pos,add,lson);
 89     else         update(pos,add,rson);
 90     push_up(rt);
 91 }
 92 
 93 int query_sum(int L,int R,int l,int r,int rt)
 94 {
 95     if(L <= l && R >= r)
 96     {
 97         return sum[rt];
 98     }
 99     int m = (l+r)>>1 , ans = 0;
100     if(L <= m) ans += query_sum(L,R,lson);
101     if(R >  m) ans += query_sum(L,R,rson);
102     return ans;
103 }
104 
105 int query_max(int L,int R,int l,int r,int rt)
106 {
107     if(L <= l && R >= r)
108     {
109         //printf("[%d,%d] rt:%d mx:%d\n",l,r,rt,mx[rt]);
110         return mx[rt];
111     }
112     int m = (l+r)>>1 , ans = -INF;
113     if(L <= m) ans = max(ans,query_max(L,R,lson));
114     if(R >  m) ans = max(ans,query_max(L,R,rson));
115     return ans;
116 }
117 
118 int Find_sum(int u,int v)
119 {
120     int fu = top[u],fv = top[v];
121     int ans = 0;
122     while(fu != fv)
123     {
124         //printf("ans:%d %d %d %d %d\n",ans,u,fu,v,fv);
125         if(dep[fu] < dep[fv])
126         {
127             swap(u,v);
128             swap(fu,fv);
129         }
130         ans += query_sum(id[fu],id[u],root);
131         u = fa[fu];
132         fu = top[u];
133     }
134     if(u == v)
135     {
136         return ans+query_sum(id[u],id[v],root);
137     }
138     else{
139         if(dep[u] < dep[v]) swap(u,v);
140         return ans+query_sum(id[v],id[u],root);
141     }
142 }
143 
144 int Find_max(int u,int v)
145 {
146     int fu = top[u],fv = top[v];
147     int ans = -INF;
148     while(fu != fv)
149     {
150         if(dep[fu] < dep[fv])
151         {
152             swap(u,v);
153             swap(fu,fv);
154         }
155         //printf("ans:%d %d %d %d %d\n",ans,u,fu,v,fv);
156         //printf("q:%d\n",query_max(id[fu],id[u],root));
157         ans = max(ans,query_max(id[fu],id[u],root));
158         u = fa[fu];
159         fu = top[u];
160     }
161     if(u == v)
162     {
163         return max(ans,query_max(id[u],id[v],root));
164     }
165     else{
166         if(dep[u] < dep[v]) swap(u,v);
167         return max(ans,query_max(id[v],id[u],root));
168     }
169 }
170 
171 //////////////////////////////////////////
172 
173 int N,Q;
174 int main()
175 {
176     freopen("input.in","r",stdin);
177     while(~scanf("%d",&N))
178     {
179         for(int i=1,u,v;i<N;i++)
180         {
181             scanf("%d%d",&u,&v);
182             G[u].push_back(v);
183             G[v].push_back(u);
184         }
185         for(int i=1;i<=N;i++) scanf("%d",&pre_val[i]);
186         topw = 0;
187         dfs_1(1,0,1);
188         dfs_2(1,1);
189         for(int i=1;i<=N;i++) val[id[i]] = pre_val[i];
190         build(root);
191 
192         scanf("%d",&Q);
193         char op[10];
194         int a,b;
195         while(Q--)
196         {
197             scanf("%s%d%d",op,&a,&b);
198             if(op[0] == 'Q')
199             {
200                 if(op[1] == 'M')
201                 {
202                     printf("%d\n",Find_max(a,b));
203                 }else
204                 {
205                     printf("%d\n",Find_sum(a,b));
206                 }
207             }else
208             {
209                 update(id[a],b,root);
210             }
211         }
212         for(int i=0;i<=N;i++) G[i].clear();
213     }
214 }

 

posted @ 2016-07-14 14:32  Helica  阅读(338)  评论(0编辑  收藏  举报