POJ - 3237 Tree(树剖 + 区间修改)
2015-10-15 23:21
309 查看
题目大意:给你一棵树,然后给你三种操作
C i v:将第i条边的权值变成v
N a b:将a到b的所有的边的权值取相反数
Q a b:将a到b的边的最大值输出来
解题思路:用线段树维护两个值,一个是最大值,一个是最小值
当区间取反的时候,交换最大值跟最小值,然后两个取相反数就可以了
还有一点要注意的,区间修改的lazy标志,并不是传递下去的,而是分奇偶的,因为区间被取相反数偶数次的话,就相当于不变了
C i v:将第i条边的权值变成v
N a b:将a到b的所有的边的权值取相反数
Q a b:将a到b的边的最大值输出来
解题思路:用线段树维护两个值,一个是最大值,一个是最小值
当区间取反的时候,交换最大值跟最小值,然后两个取相反数就可以了
还有一点要注意的,区间修改的lazy标志,并不是传递下去的,而是分奇偶的,因为区间被取相反数偶数次的话,就相当于不变了
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 10010; const int M = 10010 << 2; const int INF = 0x3f3f3f3f; struct Edge{ int u, v, dis, next; Edge() {} Edge(int u, int v, int dis, int next): u(u), v(v), dis(dis), next(next){} }E[N * 2]; int head , size , son , f , top , dep , id ; int n, tot, idx; int val[M], mark[M], Min[M], Max[M]; void PushUp(int u) { Max[u] = max(Max[u << 1], Max[u << 1 | 1]); Min[u] = min(Min[u << 1], Min[u << 1 | 1]); } void build(int u, int l, int r) { mark[u] = 0; if (l == r) { Min[u] = Max[u] = val[l]; return ; } int mid = (l + r) >> 1; build(u << 1, l, mid); build(u << 1 | 1, mid + 1, r); PushUp(u); } void dfs1(int u, int fa, int depth) { size[u] = 1; f[u] = fa; dep[u] = depth; son[u] = 0; for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (v == fa) continue; dfs1(v, u, depth + 1); size[u] += size[v]; if (size[v] > size[son[u]]) son[u] = v; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++idx; if (son[u]) dfs2(son[u], tp); for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (v == f[u] || v == son[u]) continue; dfs2(v, v); } } void PushDown(int u, int l, int r) { mark[u << 1] += mark[u]; mark[u << 1 | 1] += mark[u]; Max[u << 1] = -Max[u << 1]; Min[u << 1] = -Min[u << 1]; Min[u << 1 | 1] = -Min[u << 1 | 1]; Max[u << 1 | 1] = -Max[u << 1 | 1]; swap(Min[u << 1], Max[u << 1]); swap(Min[u << 1 | 1], Max[u << 1 | 1]); mark[u] = 0; } int Query(int u, int l, int r, int L, int R) { if (L <= l && r <= R) return Max[u]; if (mark[u] % 2) PushDown(u, l, r); int mid = (l + r) >> 1; if (R <= mid) return Query(u << 1, l, mid, L, R); else if (L > mid) return Query(u << 1 | 1, mid + 1, r, L, R); else return max(Query(u << 1, l, mid, L, mid), Query(u << 1 | 1, mid + 1, r, mid + 1, R)); } void Modify(int u, int l, int r, int L, int R, int c, int flag) { if (l == L && r == R) { if (flag) Min[u] = Max[u] = c; else { mark[u] += 1; swap(Min[u], Max[u]); Min[u] = -Min[u]; Max[u] = -Max[u]; } return ; } int mid = (l + r) >> 1; if (mark[u] % 2) PushDown(u, l, r); if (R <= mid) Modify(u << 1, l, mid, L, R, c, flag); else if (L > mid) Modify(u << 1 | 1, mid + 1, r, L, R, c, flag); else { Modify(u << 1, l, mid, L, mid, c, flag); Modify(u << 1 | 1, mid + 1, r, mid + 1, R, c, flag); } PushUp(u); } void gao(int u, int v, int flag) { int tp1 = top[u], tp2 = top[v]; int ans = -INF; while (tp1 != tp2) { if (dep[tp1] < dep[tp2]) { swap(tp1, tp2); swap(u, v); } if (flag) ans = max(ans, Query(1, 1, idx, id[tp1], id[u])); else Modify(1, 1, idx, id[tp1], id[u], -1, flag); u = f[tp1]; tp1 = top[u]; } if (u != v) { if (dep[u] > dep[v]) swap(u ,v); if (flag) ans = max(ans, Query(1, 1, idx, id[son[u]], id[v])); else Modify(1, 1, idx, id[son[u]], id[v], -1, flag); } if (flag) printf("%d\n", ans); } void solve() { char op[30]; int a, b; while (scanf("%s", op) && op[0] != 'D') { scanf("%d%d", &a, &b); if (op[0] == 'Q') gao(a, b, 1); else if (op[0] == 'C'){ int l = id[E[2 * (a - 1)].u]; Modify(1, 1, idx, l, l, b, 1); } else gao(a, b, 0); } } void AddEdge(int u, int v, int dis) { E[tot] = Edge(u, v, dis, head[u]); head[u] = tot++; E[tot] = Edge(v, u, dis, head[v]); head[v] = tot++; } void init() { scanf("%d", &n); memset(head, -1, sizeof(head)); tot = 0; int u, v, dis; for (int i = 1; i < n; i++) { scanf("%d%d%d", &u, &v, &dis); AddEdge(u, v, dis); } idx = 0; dfs1(1, 0, 1); dfs2(1, 1); for (int i = 0; i < tot; i += 2) { if (dep[E[i].u] < dep[E[i].v]) swap(E[i].u, E[i].v); val[id[E[i].u]] = E[i].dis; } build(1, 1, idx); } int main() { int test; scanf("%d", &test); while (test--) { init(); solve(); } return 0; }
相关文章推荐
- 美图吴欣鸿:将基于00后去做社交
- swift 2.0 函数
- 不能清除错误的资源,怎么办
- 软件、网站测试
- Linux学习 -- 启动管理
- Unity3D中级开发工程师面试指导
- C/C++函数参数的入栈顺序,计算顺序和可变参数的实现
- 五大手势
- 实验设计与排错之四OSPF配置、分析与排错
- <LeetCode><Easy> 203 Happy Number
- IDEA 14在MAC下如何对tomcat进行远程调试
- error while crawling /home/$USER: boost::filesystem::status: Permission denied: “/home$USER/.gvfs”
- CentOS使用心得
- 转载;字典转模型
- 003用LabVIEW和Arduino开发一个温度采集系统
- WXHL学习文章连载 十四
- 乐视:产品都是周边,撕X才是本体
- mac实用脚本
- 通过snmp v2读取cisco 3560上的 mac-address-table 的问题
- C语言,3个数中的求最大数