标签:
题目链接: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 }
标签:
原文地址:http://www.cnblogs.com/titicia/p/4902389.html