poj3237
2015-07-06 00:47
211 查看
这题同样是要将边权下放到点
这题要注意的是negate询问,是将权值取反,因为是区间修改,要用到laze标记
但是要注意的是,如果有标记下放的时候,如果下边已经有标记了, 那么就是取反,再取反, 所以只要将标记去除就行了
就因为这个wa了好几发
同时,线段树也要维护一个最小值,因为取反之后,最小值就变成最大值了
这题要注意的是negate询问,是将权值取反,因为是区间修改,要用到laze标记
但是要注意的是,如果有标记下放的时候,如果下边已经有标记了, 那么就是取反,再取反, 所以只要将标记去除就行了
就因为这个wa了好几发
同时,线段树也要维护一个最小值,因为取反之后,最小值就变成最大值了
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #include <iostream> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <string> #include <math.h> #pragma warning(disable:4996) #pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; const int INF = 1<<30; const int N = 100000 + 10; int size , fa , depth , son , w , top , num; int Max[N * 4], Min[N * 4]; int col[N * 4]; std::vector<int> g ; int edge [3]; void dfs(int u) { size[u] = 1; son[u] = 0; for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if (v != fa[u]) { depth[v] = depth[u] + 1; fa[v] = u; dfs(v); size[u] += size[v]; if (size[v]>size[son[u]]) son[u] = v; } } } void dfs2(int u, int tp) { w[u] = ++num; top[u] = tp; if (son[u] != 0) dfs2(son[u], top[u]); for (int i = 0; i < g[u].size(); ++i) { int v = g[u][i]; if (v != son[u] && v != fa[u]) dfs2(v, v); } } void pushUp(int rt) { Max[rt] = std::max(Max[rt << 1], Max[rt << 1 | 1]); Min[rt] = std::min(Min[rt << 1], Min[rt << 1 | 1]); } void pushDown(int rt) { if (col[rt]) { //col[rt << 1] = col[rt << 1 | 1] = col[rt]; // 注意标记的下放 col[rt << 1] ^= 1; col[rt << 1 | 1] ^= 1; int tmp = Max[rt << 1]; Max[rt << 1] = -Min[rt << 1]; Min[rt << 1] = -tmp; tmp = Max[rt << 1 | 1]; Max[rt << 1 | 1] = -Min[rt << 1 | 1]; Min[rt << 1 | 1] = -tmp; col[rt] = 0; } } void change(int l, int r, int rt, int pos, int val) { pushDown(rt); if (l == r) { Min[rt] = Max[rt] = val; return; } int mid = (l + r) >> 1; if (pos <= mid) change(l, mid, rt << 1, pos, val); else change(mid + 1, r, rt << 1 | 1, pos, val); pushUp(rt); } void negate(int l, int r, int rt, int L, int R) { pushDown(rt); if (L <= l && R >= r) { int tmp = Max[rt]; Max[rt] = -Min[rt]; Min[rt] = -tmp; col[rt] = 1; return; } int mid = (l + r) >> 1; if (L <= mid) negate(l, mid, rt << 1, L, R); if (R > mid) negate(mid + 1, r, rt << 1 | 1, L, R); pushUp(rt); } int ans ; void query(int l, int r, int rt, int L, int R) { pushDown(rt); if (L <= l && R >= r) { ans = std::max(ans, Max[rt]); return; } int mid = (l + r) >> 1; if (L <= mid) query(l, mid, rt << 1, L, R); if (R > mid) query(mid + 1, r, rt << 1 | 1, L, R); pushUp(rt); } int main() { //freopen("d:/in.txt", "r", stdin); int t, n, a, b; char op[11]; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; ++i) g[i].clear(); memset(col, 0, sizeof(col)); num = 0; for (int i = 1; i < n; ++i) { scanf("%d%d%d", &edge[i][0], &edge[i][1], &edge[i][2]); g[edge[i][0]].push_back(edge[i][1]); g[edge[i][1]].push_back(edge[i][0]); } depth[1] = fa[1] = 0; dfs(1); dfs2(1, 1); for (int i = 1; i < n; ++i) { if (depth[edge[i][0]] > depth[edge[i][1]]) std::swap(edge[i][0], edge[i][1]); change(1, n, 1, w[edge[i][1]], edge[i][2]); } while (true) { scanf("%s", op); if (op[0] == 'D') break; scanf("%d%d", &a, &b); if (op[0] == 'Q') { ans = -INF; while (top[a] != top[b]) { if (depth[top[a]] < depth[top[b]]) std::swap(a, b); query(1, n, 1, w[top[a]], w[a]); a = fa[top[a]]; } if (a == b) { printf("%d\n", ans); continue; } if (depth[a]>depth[b]) std::swap(a, b); query(1, n, 1, w[son[a]], w[b]); printf("%d\n", ans); } else if (op[0] == 'C') { change(1, n, 1, w[edge[a][1]], b); } else { while (top[a] != top[b]) { if (depth[top[a]] < depth[top[b]]) std::swap(a, b); negate(1, n, 1, w[top[a]], w[a]); a = fa[top[a]]; } if (a == b) continue; if (depth[a]>depth[b]) std::swap(a, b); negate(1, n, 1, w[son[a]], w[b]); } } } return 0; }
相关文章推荐
- iOS开发之控件frame/bounds/center尺寸快速赋值改变小技巧-简单给UIView新增分类
- 代理设计模式
- 如何监控MYSQL消耗服务器资源
- 「深入 Exchange 2013」09 证书
- MD5加密工具类
- <<代码的未来>>读书笔记
- 详解 Spotlight on MySQL监控MySQL服务器
- PHP 错误与异常 笔记与总结(16 )自定义异常处理器
- android项目源码
- POJ 2955 Brackets (区间dp 括号匹配)
- android项目源码
- java开源项目
- java开源项目
- 对正在运行的mysql进行监控
- delete
- delete
- FZU2082
- display:none | visibility:hidden 的区别
- MyBatis入门
- linux 启动oracle报cannot restore segment prot after reloc: Permission denied