POJ 3237 - Tree(树链剖分)
来源:互联网 发布:仿商城html5源码 编辑:程序博客网 时间:2024/04/29 16:47
题目:
http://poj.org/problem?id=3237
题意:
给出有边权的一棵树,三个操作:
1.修改边权。
2.将u->v 的路径边权取反。
3.输出u->v 路径的最大边权。
AC.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int inf = 0x3f3f3f3f;const int maxn = 1e5+5;int deep[maxn], top[maxn], fa[maxn], num[maxn], p[maxn], fp[maxn], son[maxn];int pos;int tot, head[maxn];struct Edge{ int to, next;}edge[maxn*2];void init(){ tot = 0; memset(head, -1, sizeof(head)); pos = 0; memset(son, -1, sizeof(son));}void addedge(int u, int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++;}void dfs1(int u, int pre, int d){ deep[u] = d; fa[u] = pre; num[u] = 1; for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(v != pre) { dfs1(v, u, d+1); num[u] += num[v]; if(son[u] == -1 || num[v] > num[son[u]]) { son[u] = v; } } }}void getpos(int u, int sp){ top[u] = sp; p[u] = pos++; fp[p[u]] = u; if(son[u] == -1) return; getpos(son[u], sp); for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(v != son[u] && v != fa[u]) { getpos(v, v); } }}struct Node{ int l, r; int Max, Min, ne;}segtree[maxn*3];void build(int i, int l, int r){ segtree[i].l = l; segtree[i].r = r; segtree[i].Max = 0; segtree[i].Min = 0; segtree[i].ne = 0; if(l == r) return; int mid = (l+r)/2; build(i<<1, l, mid); build((i<<1)|1, mid+1, r);}void push_up(int i){ segtree[i].Max = max(segtree[i<<1].Max, segtree[(i<<1)|1].Max); segtree[i].Min = min(segtree[i<<1].Min, segtree[(i<<1)|1].Min);}void push_down(int i){ if(segtree[i].l == segtree[i].r) return; if(segtree[i].ne) { segtree[i<<1].Max = -segtree[i<<1].Max; segtree[i<<1].Min = -segtree[i<<1].Min; swap(segtree[i<<1].Min, segtree[i<<1].Max); segtree[(i<<1)|1].Max = -segtree[(i<<1)|1].Max; segtree[(i<<1)|1].Min = -segtree[(i<<1)|1].Min; swap(segtree[(i<<1)|1].Max, segtree[(i<<1)|1].Min); segtree[i<<1].ne ^= 1; segtree[(i<<1)|1].ne ^= 1; segtree[i].ne = 0; }}void update(int i, int k, int val){ if(segtree[i].l == k && segtree[i].r == k) { segtree[i].Max = val; segtree[i].Min = val; segtree[i].ne = 0; return; } push_down(i); int mid = (segtree[i].l + segtree[i].r)/2; if(k <= mid) update(i<<1, k, val); else update((i<<1)|1, k, val); push_up(i);}void ne_update(int i, int l, int r){ if(segtree[i].l == l && segtree[i].r == r) { segtree[i].Max = -segtree[i].Max; segtree[i].Min = -segtree[i].Min; swap(segtree[i].Max, segtree[i].Min); segtree[i].ne ^= 1; return; } push_down(i); int mid = (segtree[i].l + segtree[i].r) / 2; if(r <= mid) ne_update(i<<1, l, r); else if(l > mid) ne_update((i<<1)|1, l, r); else { ne_update(i<<1, l, mid); ne_update((i<<1)|1, mid+1, r); } push_up(i);}int query(int i, int l, int r){ if(segtree[i].l == l && segtree[i].r == r) return segtree[i].Max; push_down(i); int mid = (segtree[i].l + segtree[i].r)/2; if(r <= mid) return query(i<<1, l, r); else if(l > mid) return query((i<<1)|1, l, r); else return max(query(i<<1, l, mid), query((i<<1)|1, mid+1, r)); push_up(i);}int find(int u, int v){ int f1 = top[u], f2 = top[v]; int tmp = -inf; while(f1 != f2) { if(deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } tmp = max(tmp, query(1, p[f1], p[u])); u = fa[f1]; f1 = top[u]; } if(u == v) return tmp; if(deep[u] > deep[v]) swap(u, v); return max(tmp, query(1, p[son[u]], p[v]));}void ne_find(int u, int v){ int f1 = top[u], f2 = top[v]; while(f1 != f2) { if(deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); } ne_update(1, p[f1], p[u]); u = fa[f1]; f1 = top[u]; } if(u == v) return ; if(deep[u] > deep[v]) swap(u, v); ne_update(1, p[son[u]], p[v]);}int e[maxn][3];int main(){ //freopen("in", "r", stdin); int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); init(); for(int i = 0; i < n-1; ++i) { int u, v, w; scanf("%d%d%d", &e[i][0], &e[i][1], &e[i][2]); addedge(e[i][0], e[i][1]); addedge(e[i][1], e[i][0]); } dfs1(1, 0, 0); getpos(1, 1); build(1, 0, pos-1); for(int i = 0; i < n-1; ++i) { if(deep[e[i][0]] > deep[e[i][1]]) swap(e[i][0], e[i][1]); update(1, p[e[i][1]], e[i][2]); } char q[10]; while(~scanf("%s", q)) { if(q[0] == 'D') break; int u, v; scanf("%d %d", &u, &v); if(q[0] == 'Q') { printf("%d\n", find(u, v)); } if(q[0] == 'C') { update(1, p[e[u-1][1]], v); } if(q[0] == 'N') { ne_find(u, v); } } } return 0;}
0 0
- POJ 3237 Tree 树链剖分
- 【POJ】3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- 【树链剖分】 POJ 3237 Tree
- poj 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree 树链剖分
- POJ 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- poj 3237 Tree 树链剖分
- POJ 3237 - Tree(树链剖分)
- poj 3237 Tree 树链剖分
- POJ 3237Tree 树链剖分
- POJ 3237 Tree 树链剖分
- POJ-3237Tree(树链剖分)
- poj 3237 Tree(树链剖分)
- POJ 3237 Tree (树链剖分)
- POJ 3237 Tree(树链剖分模板)
- Java多线程[3]:线程同步(互斥)
- Redhat下mysql的安装与使用
- 学习笔记 - InputStreamReader封装System.in,最后用BufferedReader封装
- Myeclipse run as 只有Run Configurations
- Kafka简单测试demo
- POJ 3237 - Tree(树链剖分)
- DOM对象和jQuery对象之间的相互转换
- iOS UITableView(表格)
- DefaultServlet int Tomcat
- flume学习(六):使用hive来分析flume收集的日志数据
- 在执行批处理时将执行错误的语句记录下来并写到日志文件中去
- Mac 软件“Android 文件传输 v1.0”
- Android实现复制粘贴功能
- Android系统性能调优工具介绍