这题同样是要将边权下放到点
这题要注意的是negate询问,是将权值取反,因为是区间修改,要用到laze标记
但是要注意的是,如果有标记下放的时候,如果下边已经有标记了, 那么就是取反,再取反, 所以只要将标记去除就行了
就因为这个wa了好几发
同时,线段树也要维护一个最小值,因为取反之后,最小值就变成最大值了
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 #pragma warning(disable:4996) 14 #pragma comment(linker, "/STACK:1024000000,1024000000") 15 typedef long long LL; 16 const int INF = 1<<30; 17 18 const int N = 100000 + 10; 19 int size[N], fa[N], depth[N], son[N], w[N], top[N], num; 20 int Max[N * 4], Min[N * 4]; 21 int col[N * 4]; 22 std::vector<int> g[N]; 23 int edge[N][3]; 24 void dfs(int u) 25 { 26 size[u] = 1; 27 son[u] = 0; 28 for (int i = 0; i < g[u].size(); ++i) 29 { 30 int v = g[u][i]; 31 if (v != fa[u]) 32 { 33 depth[v] = depth[u] + 1; 34 fa[v] = u; 35 dfs(v); 36 size[u] += size[v]; 37 if (size[v]>size[son[u]]) 38 son[u] = v; 39 } 40 } 41 } 42 43 void dfs2(int u, int tp) 44 { 45 w[u] = ++num; 46 top[u] = tp; 47 if (son[u] != 0) 48 dfs2(son[u], top[u]); 49 for (int i = 0; i < g[u].size(); ++i) 50 { 51 int v = g[u][i]; 52 if (v != son[u] && v != fa[u]) 53 dfs2(v, v); 54 } 55 56 } 57 58 void pushUp(int rt) 59 { 60 Max[rt] = std::max(Max[rt << 1], Max[rt << 1 | 1]); 61 Min[rt] = std::min(Min[rt << 1], Min[rt << 1 | 1]); 62 } 63 void pushDown(int rt) 64 { 65 if (col[rt]) 66 { 67 //col[rt << 1] = col[rt << 1 | 1] = col[rt]; 68 // 注意标记的下放 69 col[rt << 1] ^= 1; 70 col[rt << 1 | 1] ^= 1; 71 int tmp = Max[rt << 1]; 72 Max[rt << 1] = -Min[rt << 1]; 73 Min[rt << 1] = -tmp; 74 tmp = Max[rt << 1 | 1]; 75 Max[rt << 1 | 1] = -Min[rt << 1 | 1]; 76 Min[rt << 1 | 1] = -tmp; 77 col[rt] = 0; 78 } 79 } 80 void change(int l, int r, int rt, int pos, int val) 81 { 82 pushDown(rt); 83 if (l == r) 84 { 85 Min[rt] = Max[rt] = val; 86 return; 87 } 88 int mid = (l + r) >> 1; 89 if (pos <= mid) 90 change(l, mid, rt << 1, pos, val); 91 else 92 change(mid + 1, r, rt << 1 | 1, pos, val); 93 pushUp(rt); 94 } 95 96 void negate(int l, int r, int rt, int L, int R) 97 { 98 pushDown(rt); 99 if (L <= l && R >= r) 100 { 101 int tmp = Max[rt]; 102 Max[rt] = -Min[rt]; 103 Min[rt] = -tmp; 104 col[rt] = 1; 105 return; 106 } 107 int mid = (l + r) >> 1; 108 if (L <= mid) 109 negate(l, mid, rt << 1, L, R); 110 if (R > mid) 111 negate(mid + 1, r, rt << 1 | 1, L, R); 112 pushUp(rt); 113 } 114 int ans ; 115 void query(int l, int r, int rt, int L, int R) 116 { 117 pushDown(rt); 118 if (L <= l && R >= r) 119 { 120 ans = std::max(ans, Max[rt]); 121 return; 122 } 123 int mid = (l + r) >> 1; 124 if (L <= mid) 125 query(l, mid, rt << 1, L, R); 126 if (R > mid) 127 query(mid + 1, r, rt << 1 | 1, L, R); 128 pushUp(rt); 129 } 130 int main() 131 { 132 //freopen("d:/in.txt", "r", stdin); 133 int t, n, a, b; 134 char op[11]; 135 scanf("%d", &t); 136 while (t--) 137 { 138 scanf("%d", &n); 139 for (int i = 1; i <= n; ++i) 140 g[i].clear(); 141 memset(col, 0, sizeof(col)); 142 num = 0; 143 for (int i = 1; i < n; ++i) 144 { 145 scanf("%d%d%d", &edge[i][0], &edge[i][1], &edge[i][2]); 146 g[edge[i][0]].push_back(edge[i][1]); 147 g[edge[i][1]].push_back(edge[i][0]); 148 } 149 depth[1] = fa[1] = 0; 150 dfs(1); 151 dfs2(1, 1); 152 for (int i = 1; i < n; ++i) 153 { 154 if (depth[edge[i][0]] > depth[edge[i][1]]) 155 std::swap(edge[i][0], edge[i][1]); 156 change(1, n, 1, w[edge[i][1]], edge[i][2]); 157 } 158 while (true) 159 { 160 scanf("%s", op); 161 if (op[0] == 'D') 162 break; 163 scanf("%d%d", &a, &b); 164 if (op[0] == 'Q') 165 { 166 ans = -INF; 167 while (top[a] != top[b]) 168 { 169 if (depth[top[a]] < depth[top[b]]) 170 std::swap(a, b); 171 query(1, n, 1, w[top[a]], w[a]); 172 a = fa[top[a]]; 173 } 174 if (a == b) 175 { 176 printf("%d\n", ans); 177 continue; 178 } 179 if (depth[a]>depth[b]) 180 std::swap(a, b); 181 query(1, n, 1, w[son[a]], w[b]); 182 printf("%d\n", ans); 183 } 184 else if (op[0] == 'C') 185 { 186 change(1, n, 1, w[edge[a][1]], b); 187 } 188 else 189 { 190 while (top[a] != top[b]) 191 { 192 if (depth[top[a]] < depth[top[b]]) 193 std::swap(a, b); 194 negate(1, n, 1, w[top[a]], w[a]); 195 a = fa[top[a]]; 196 } 197 if (a == b) 198 continue; 199 if (depth[a]>depth[b]) 200 std::swap(a, b); 201 negate(1, n, 1, w[son[a]], w[b]); 202 } 203 } 204 } 205 return 0; 206 }