hdu 3966 Aragorn's Story

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966

题意:

给出一棵树 节点为1-N。给出每个节点的权值。

然后有P个询问:

I C1 C2 K表示 节点C1-C2的路上每个节点权值增加K。

D C1 C2 K表示节点C1-C2的路上每个节点权值减少K。

Q C询问此时节点C的权值

思路:

权值在点上的树链剖分+线段树成端更新+线段树单点询问。

  1 #pragma comment(linker, "/STACK:1024000000,1024000000")  
  2 //#include <bits/stdc++.h>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <string>
  6 #include <iostream>
  7 #include <vector>
  8 using namespace std;
  9 #define maxn 50010
 10 #define lson l, m, rt<<1
 11 #define rson m+1, r, rt<<1|1
 12 struct Node
 13 {
 14     int to;
 15     Node(int t)
 16     {
 17         to = t;
 18     }
 19     Node(){}
 20 };
 21 vector <Node> mp[maxn];
 22 struct Edge
 23 {
 24     int from, to, val;
 25 }e[maxn];
 26 int N, M, P, pos;
 27 int cnt[maxn<<2], col[maxn<<2];
 28 int a[maxn];
 29 int siz[maxn], dep[maxn], fa[maxn], son[maxn], top[maxn];
 30 int w[maxn], fw[maxn];
 31 void PushDown(int rt, int m)
 32 {
 33     if(col[rt] != 0)
 34     {
 35         col[rt<<1] += col[rt];
 36         col[rt<<1|1] += col[rt];
 37         cnt[rt<<1] += (m-(m>>1))*col[rt];
 38         cnt[rt<<1|1] += (m>>1)*col[rt];
 39         col[rt] = 0;
 40     }
 41 }
 42 void PushUp(int rt)
 43 {
 44     cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1];
 45 }
 46 void build(int l, int r, int rt)
 47 {
 48     col[rt] = 0;
 49     if(l == r)
 50     {
 51         cnt[rt] = a[fw[l]];
 52         return;
 53     }
 54     int m = (l+r)>>1;
 55     build(lson);
 56     build(rson);
 57     PushUp(rt);
 58 }
 59 int query(int L, int R, int l, int r, int rt)
 60 {
 61     if(L <= l && R >= r)
 62     {
 63         return cnt[rt];
 64     }
 65     PushDown(rt, r-l+1);
 66     int m = (l+r)>>1;
 67     int ret = 0;
 68     if(L <= m) ret += query(L, R, lson);
 69     if(R > m) ret += query(L, R, rson);
 70     PushUp(rt);
 71     return ret;
 72 }
 73 void update(int L, int R, int c, int l, int r, int rt)
 74 {
 75     if(L <= l && R >= r)
 76     {
 77         col[rt] += c;
 78         cnt[rt] += (r-l+1)*c;
 79         return;
 80     }
 81     PushDown(rt, r-l+1);
 82     int m = (l+r)>>1;
 83     if(L <= m) update(L, R, c, lson);
 84     if(R > m) update(L, R, c, rson);
 85     PushUp(rt);
 86     
 87 }
 88 int dfs1(int u, int pre, int deep)
 89 {
 90     siz[u] = 1; fa[u] = pre; dep[u] = deep;
 91     int mmax = 0;
 92     for(int i = 0; i < mp[u].size(); i++)
 93     {
 94         if(mp[u][i].to != pre)
 95         {
 96             int temp = dfs1(mp[u][i].to, u, deep+1);
 97             siz[u] += temp;
 98             if(son[u] == -1 || temp >= mmax) 
 99             {
100                 son[u] = mp[u][i].to;
101                 mmax = temp;
102             }
103         }
104     }
105     return siz[u];
106 }
107 void dfs2(int u, int val)
108 {
109     top[u] = val;
110     if(son[u] != -1)
111     {
112         w[u] = ++pos;
113         fw[w[u]] = u;
114         dfs2(son[u], val);
115     }
116     else if(son[u] == -1)
117     {
118         w[u] = ++pos;
119         fw[w[u]] = u;
120         return;
121     }
122     for(int i = 0; i < mp[u].size(); i++)
123     {
124         if(mp[u][i].to != fa[u] && mp[u][i].to != son[u]) dfs2(mp[u][i].to, mp[u][i].to);
125     }
126 }
127 void change(int u, int v, int val)
128 {
129     int f1 = top[u], f2 = top[v];
130     while(f1 != f2)
131     {
132         if(dep[f1] < dep[f2])
133         {
134             swap(f1, f2);
135             swap(u, v);
136         }
137         update(w[f1], w[u], val, 1, pos, 1);
138         u = fa[f1]; f1 = top[u];
139     } 
140     if(dep[u] > dep[v]) swap(u,v);
141     update(w[u], w[v], val, 1, pos, 1);
142 }
143 int main() 
144 {
145    // freopen("in.txt", "r", stdin);
146     //freopen("out.txt", "w", stdout);
147     while(~scanf("%d%d%d", &N, &M, &P))
148     {
149         for(int i = 1; i <= N; i++) mp[i].clear(); 
150         pos = 0; memset(son, -1, sizeof(son));
151         for(int i = 1; i <= N; i++) scanf("%d", &a[i]);
152         for(int i = 1; i <= M; i++)
153         {
154             int a, b; scanf("%d%d", &a, &b);
155             mp[a].push_back(Node(b));
156             mp[b].push_back(Node(a));
157         }
158         dfs1(1, -1, 1);
159         dfs2(1, 1);
160         build(1, pos, 1);
161 
162         char op[5];
163         while(P--)
164         {
165             scanf("%s", op); int c1, c2, k;
166             if(op[0] == 'I') 
167             {
168                 scanf("%d%d%d", &c1, &c2, &k);
169                 change(c1, c2, k);
170             }
171             else if(op[0] == 'D')
172             {
173                 scanf("%d%d%d", &c1, &c2, &k);
174                 change(c1, c2, -k);
175             }
176             else if(op[0] == 'Q') 
177             {
178                 int temp; scanf("%d", &temp);
179                 printf("%d\n", query(w[temp], w[temp], 1, pos, 1));
180             }
181         }
182 
183 
184     }
185     return 0;
186 }

 

posted @ 2015-10-22 18:39  下周LGD该赢了吧  阅读(139)  评论(0编辑  收藏  举报