码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3966 RE 树链剖分 Aragorn's Story

时间:2015-08-06 14:47:52      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

给一棵点带权的图

有这样一个操作:

  • 使树上某一条路径所有点权值增减

每次询问某个点现在的权值。

树链剖分完以后,就是线段树的成段更新了。

这题感觉A不了了,无限RE,手动开栈也没卵用。

还是把我辛辛苦苦写的代码贴一下吧。

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn = 50000 + 10;
  9 const int INF = 0x3f3f3f3f;
 10 
 11 void scan(int& x)
 12 {
 13     x = 0;
 14     bool flag = false;
 15     char c =  ;
 16     while(c != - && (c < 0 || c > 9)) c = getchar();
 17     if(c == -) { flag = true; c = getchar(); }
 18     while(c >= 0 && c <= 9) { x = x * 10 + c - 0; c = getchar(); }
 19     if(flag) x = -x;
 20 }
 21 
 22 int n, m, Q;
 23 
 24 vector<int> G[maxn];
 25 int val[maxn];
 26 
 27 int tot;
 28 int L[maxn];
 29 int fa[maxn];
 30 int id[maxn];
 31 int top[maxn];
 32 int sz[maxn];
 33 int son[maxn];
 34 
 35 void dfs(int u)
 36 {
 37     sz[u] = 1;
 38     son[u] = 0;
 39     for(int i = 0; i < G[u].size(); i++)
 40     {
 41         int v = G[u][i];
 42         if(v == fa[u]) continue;
 43         fa[v] = u;
 44         L[v] = L[u] + 1;
 45         dfs(v);
 46         sz[u] += sz[v];
 47         if(sz[v] > sz[son[u]]) son[u] = v;
 48     }
 49 }
 50 
 51 void dfs2(int u, int tp)
 52 {
 53     top[u] = tp;
 54     id[u] = ++tot;
 55     if(son[u]) dfs2(son[u], tp);
 56     for(int i = 0; i < G[u].size(); i++)
 57     {
 58         int v = G[u][i];
 59         if(v == fa[u] || v == son[u]) continue;
 60         dfs2(v, v);
 61     }
 62 }
 63 
 64 int vv;
 65 int add[maxn << 2];
 66 
 67 void update(int o, int L, int R, int qL, int qR)
 68 {
 69     if(qR < L || qL > R) return ;
 70     if(qL <= L && R <= qR) { add[o] += vv; return ; }
 71     int M = (L + R) / 2;
 72     update(o<<1, L, M, qL, qR);
 73     update(o<<1|1, M+1, R, qL, qR);
 74 }
 75 
 76 int query(int o, int L, int R, int p)
 77 {
 78     if(L == R) return add[o];
 79     int M = (L + R) / 2;
 80     add[o<<1] += add[o];
 81     add[o<<1|1] += add[o];
 82     add[o] = 0;
 83     if(p <= M) return query(o<<1, L, M, p);
 84     return query(o<<1|1, M+1, R, p);
 85 }
 86 
 87 void Update(int u, int v)
 88 {
 89     int t1 = top[u], t2 = top[v];
 90     while(t1 != t2)
 91     {
 92         if(L[t1] < L[t2]) { swap(t1, t2); swap(u, v); }
 93         update(1, 1, tot, id[t1], id[u]);
 94         u = fa[t1], t1 = top[u];
 95     }
 96     if(u == v) return ;
 97     if(L[u] < L[v]) swap(u, v);
 98     update(1, 1, tot, id[v], id[u]);
 99 }
100 
101 int main()
102 {
103     while(scanf("%d%d%d", &n, &m, &Q) == 3)
104     {
105         for(int i = 1; i <= n; i++) { G[i].clear(); scan(val[i]); }
106         for(int i = 1; i < n; i++)
107         {
108             int u, v; scan(u); scan(v);
109             G[u].push_back(v); G[v].push_back(u);
110         }
111 
112         L[1] = fa[1] = 0;
113         dfs(1);
114         tot = 0;
115         dfs2(1, 1);
116 
117         memset(add, 0, sizeof(add));
118         char op[10];
119         while(Q--)
120         {
121             int x, y;
122             scanf("%s", op);
123             if(op[0] == Q)
124             {
125                 scan(x);
126                 printf("%d\n", val[x] + query(1, 1, tot, x));
127             }
128             else
129             {
130                 scan(x); scan(y); scan(vv);
131                 if(op[0] == D) vv = -vv;
132                 Update(x, y);
133             }
134         }
135     }
136 
137     return 0;
138 }
代码君

 

HDU 3966 RE 树链剖分 Aragorn's Story

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4707822.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!