poj3237

这题同样是要将边权下放到点

这题要注意的是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 }

 

posted @ 2015-07-06 00:47  justPassBy  阅读(394)  评论(0编辑  收藏  举报