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 }

 

你可能感兴趣的:(poj)