题意:一棵树上两种操作,操作1,改变u到v的每一点的值增加k,操作2,改变u到v每一条边值增加k。最后结束时问,每一点和每一条边的值。
初始时,点和边的值都为0.
分析:
很显然要用树链剖分,将点和边分别划分成连续一段的编号,然后就是维护一段一段的值了,给它增加一个值,由于题目只需要输出最后结果,那么可以用树桩数组维护。
以边为例,对于l~r的每个值增加k,利用树桩数组v[i]表示第i个值与前一个值的差值,那么第k条边的值就是sum{v[i]| 1 <= i <= k},更新时则只要给v[l]加k,给v[r+1]加(- k), 这个都可以累加下来,最后依次对每个v[i]更新,然后求出结果就行了。
代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <vector> 4 #include <map> 5 #include <cstring> 6 #include <set> 7 #include <bitset> 8 #include <cstdio> 9 #include <cmath> 10 #define esp 1e-8 11 #pragma comment(linker, "/STACK:102400000,102400000") 12 #define in freopen("F:\\rootial\\data\\data.txt", "r", stdin); 13 #define IN freopen("solve_in.txt", "r", stdin); 14 #define out freopen("out.txt", "w", stdout); 15 #define pf(x) ((x)*(x)) 16 #define lowbit(x) ((x)&(-(x))) 17 #define bug(x) printf("Line %d: >>>>>>\n", (x)); 18 #define lson l, m, rt<<1 19 #define rson m+1, r, rt<<1|1 20 #define pb push_back 21 #define mp make_pair 22 #define pi acos(-1.0) 23 #define pf(x) ((x)*(x)) 24 25 using namespace std; 26 typedef long long LL; 27 typedef pair<int, int> PII; 28 typedef map<LL, LL> MPS; 29 typedef MPS::iterator IT; 30 31 const int maxn = (int)1e5 + 100; 32 LL vv[2][maxn]; 33 int n, m; 34 int top[maxn], num[maxn], tnum[maxn], ID[maxn], son[maxn], sz[maxn], fa[maxn], dep[maxn], tmp[maxn]; 35 int cnt; 36 37 struct Edge 38 { 39 int v, id; 40 Edge() {} 41 Edge(int v, int id):v(v), id(id) {} 42 } edge[maxn*2]; 43 int fi[maxn], nxt[maxn*2]; 44 LL q[2][maxn]; 45 46 void update(int x, LL v[], LL val) 47 { 48 while(x <= n) 49 { 50 v[x] +=val; 51 x += lowbit(x); 52 } 53 } 54 void update(int l, int r, LL val, LL v[]) 55 { 56 update(l, v, val); 57 update(r+1, v, -val); 58 } 59 60 void query(int x, LL &res1, LL &res2) 61 { 62 res1 = 0, res2 = 0; 63 while(x > 0) 64 { 65 res1 += vv[0][x]; 66 res2 += vv[1][x]; 67 x -= lowbit(x); 68 } 69 } 70 void dfs1(int u, int f) 71 { 72 fa[u] = f; 73 dep[u] = dep[f] + 1; 74 sz[u] = 1; 75 for(int i = fi[u]; i; i = nxt[i]) 76 { 77 int v = edge[i].v; 78 int id = edge[i].id; 79 if(v == f) 80 continue; 81 tmp[v] = id; 82 dfs1(v, u); 83 sz[u] += sz[v]; 84 if(sz[son[u]] < sz[v]) 85 son[u] = v; 86 } 87 } 88 void dfs2(int u, int f) 89 { 90 if(son[u]) 91 { 92 num[son[u]] = ++cnt; 93 top[son[u]] = top[u]; 94 ID[tmp[son[u]]] = cnt; 95 dfs2(son[u], u); 96 } 97 for(int i = fi[u]; i; i = nxt[i]) 98 { 99 int v = edge[i].v; 100 int id = edge[i].id; 101 if(v == f || v == son[u]) continue; 102 top[v] = v; 103 num[v] = ++cnt; 104 ID[tmp[v]] = cnt; 105 dfs2(v, u); 106 } 107 } 108 void init() 109 { 110 for(int i = 0; i <= n; i++) 111 { 112 vv[0][i] = vv[1][i] = 0; 113 son[i] = 0; 114 sz[i] = 0; 115 fa[i] = 0; 116 cnt = 0; 117 fi[i] = 0; 118 nxt[i<<1] = nxt[i<<1|1] = 0; 119 q[0][i] = q[1][i] = 0; 120 } 121 } 122 void add(int u, int v, int x) 123 { 124 edge[++cnt] = Edge(v, x); 125 nxt[cnt] = fi[u]; 126 fi[u] = cnt; 127 edge[++cnt] = Edge(u, x); 128 nxt[cnt] = fi[v]; 129 fi[v] = cnt; 130 } 131 void input() 132 { 133 scanf("%d%d", &n, &m); 134 init(); 135 for(int i = 1; i < n; i++) 136 { 137 int u, v; 138 scanf("%d%d", &u, &v); 139 add(u, v, i); 140 } 141 cnt = 0; 142 } 143 inline bool isdigit(char ch) 144 { 145 return ch >= ‘0‘ && ch <= ‘9‘; 146 } 147 const LL B = (int)1e5 + 10; 148 149 void update(int u, int v, int k) //dian 150 { 151 while(top[u] != top[v]) 152 { 153 if(dep[top[u]] < dep[top[v]]) swap(u, v); 154 q[0][num[top[u]]] += k; 155 q[0][num[u]+1] -= k; 156 u = fa[top[u]]; 157 } 158 if(dep[u] < dep[v]) swap(u, v); 159 q[0][num[v]] += k; 160 q[0][num[u]+1] -= k; 161 } 162 void update1(int u, int v, int k) //bian 163 { 164 while(top[u] != top[v]) 165 { 166 if(dep[top[u]] < dep[top[v]]) swap(u, v); 167 if(u != top[u]) 168 { 169 q[1][num[son[top[u]]]] += k; 170 q[1][num[u]+1] -= k; 171 } 172 u = top[u]; 173 q[1][num[u]] += k; 174 q[1][num[u]+1] -= k;; 175 u = fa[u]; 176 } 177 if(dep[u] < dep[v]) swap(u, v); 178 if(u != v) 179 { 180 q[1][num[son[v]]] += k; 181 q[1][num[u]+1] -= k; 182 } 183 } 184 LL ans[maxn]; 185 186 void solve() 187 { 188 dfs1(1, 0); 189 top[1] = 1; 190 num[1] = ++cnt; 191 dfs2(1, 0); 192 for(int i = 0; i < m; i++) 193 { 194 char s[20]; 195 int u, v, k; 196 scanf("%s%d%d%d", s, &u, &v, &k); 197 if(strcmp(s, "ADD1") == 0) 198 { 199 update(u, v, k); 200 } 201 else 202 { 203 update1(u, v, k); 204 } 205 } 206 for(int k = 0; k < 2; k++){ 207 for(int i = 1; i <= n; i++) 208 update(i, vv[k], q[k][i]); 209 } 210 211 for(int i = 1; i <= n; i++) 212 { 213 LL res1, res2; 214 query(num[i], res1, res2); 215 ans[num[i]] = res2; 216 printf("%I64d%c", res1, i == n ? ‘\n‘ : ‘ ‘); 217 } 218 for(int i = 1; i <= n-1; i++) 219 { 220 LL res = ans[ID[i]]; 221 printf("%I64d%c", res, i == n-1 ? ‘\n‘ : ‘ ‘); 222 } 223 if(n == 1) 224 puts(""); 225 } 226 int main() 227 { 228 229 int T; 230 for(int t = scanf("%d", &T); t <= T; t++) 231 { 232 printf("Case #%d:\n", t); 233 input(); 234 solve(); 235 } 236 return 0; 237 }
时间: 2024-10-25 13:31:06