spoj375 Query on a tree 树链剖分
来源:互联网 发布:张伯伦数据统计 编辑:程序博客网 时间:2024/05/17 02:56
题目大意
链接请点我
给一棵树,有两种操作,一种是改变某一条边的边权,一种是询问某两个结点间的路径的最大值
解题
具体思路参见2009年集训队漆子超的论文《分治算法在树的路径问题中的应用》
树链剖分裸题,无奈昨天一直TLE,非常怨念,今天重写了一发,居然A了,虽然也不快,3.89s
感觉我用的姿势应该是能看得下去的……
CODE
#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn = 10010;const int inf = 0x3fffffff;int max(int a, int b) { return a > b ? a : b;}struct edge { int v, next; edge() {} edge(int a, int b) : v(a), next(b) {}};edge e[maxn*3];struct data { int x, y, d;};data E[maxn<<1];int head[maxn], son[maxn], sz[maxn], pre[maxn], top[maxn], dep[maxn], hash[maxn];int n, num, tot;void add(int u, int v) { e[tot] = edge(v, head[u]); head[u] = tot++; e[tot] = edge(u, head[v]); head[v] = tot++;}void dfs(int u, int d) { sz[u] = 1; son[u] = 0; dep[u] = d; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if (v == pre[u]) continue; pre[v] = u; dfs(v, d+1); sz[u] += sz[v]; if (sz[v] > sz[son[u]]) son[u] = v; }}void build_tree(int u, int fa) { hash[u] = ++num; top[u] = fa; if (son[u]) build_tree(son[u], top[u]); for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if (v == pre[u] || v == son[u]) continue; build_tree(v, v); }}#define lson l, m, rt<<1#define rson m+1, r, rt<<1|1int mx[maxn<<2];void PushUp(int rt) { mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);}void build(int l, int r, int rt) { mx[rt] = -inf; if (l == r) return; int m = (l+r) >> 1; build(lson); build(rson);}void update(int pos, int x, int l, int r, int rt) { if (l == r) { mx[rt] = x; return; } int m = (l+r) >> 1; if (pos <= m) update(pos, x, lson); else update(pos, x, rson); PushUp(rt);}int query(int ll, int rr, int l, int r, int rt) { if (ll <= l && rr >= r) return mx[rt]; int m = (l+r) >> 1; int res = -inf; if (ll <= m) res = max(res, query(ll, rr, lson)); if (rr > m) res = max(res, query(ll, rr, rson)); return res;}int Query(int x, int y) { int ans = -inf; while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); ans = max(ans, query(hash[top[x]], hash[x], 2, n, 1)); x = pre[top[x]]; } if (dep[x] > dep[y]) swap(x, y); if (x != y) ans = max(ans, query(hash[x]+1, hash[y], 2, n, 1)); return ans;}void solve() { scanf("%d", &n); memset(head, -1, sizeof(head)); tot = 0; for (int i = 1; i < n; i++) { scanf("%d%d%d", &E[i].x, &E[i].y, &E[i].d); add(E[i].x, E[i].y); } sz[0] = 0; num = 0; dfs(1, 1); build_tree(1, 1); build(2, n, 1); for (int i = 1; i < n; i++) { if (dep[E[i].x] < dep[E[i].y]) swap(E[i].x, E[i].y); update(hash[E[i].x], E[i].d, 2, n, 1); } char op[10]; while (1) { scanf("%s", op); if (op[0] == 'D') break; int x, y; scanf("%d%d", &x, &y); if (op[0] == 'C') update(hash[E[x].x], y, 2, n, 1); else if (op[0] == 'Q') printf("%d\n", Query(x, y)); }}int main() { int cs; scanf("%d", &cs); while (cs--) solve(); return 0;}
0 0
- SPOJ375--Query on a tree(树链剖分)
- spoj375 Query on a tree 树链剖分
- spoj375 Query on a tree 树链剖分
- 【树链剖分】spoj375 Query on a tree
- kyeremal-spoj375-Query on a tree-树链剖分
- spoj375 Query on a tree(树链剖分)
- 【SPOJ375】Query on a tree-树链剖分
- [SPOJ375]Query on a tree
- SPOJ375 Query on a tree
- SPOJ375 Query on a tree
- spoj375 Query on a tree
- 树链剖分+线段树 spoj375 Query on a tree
- 【SPOJ375】 Query on a tree——树链剖分
- Spoj375 Query on a tree 裸·树链剖分
- SPOJ375 QTREE - Query on a tree
- Spoj375.Query on a tree——树链剖分+线段树(基于边权)
- 【spoj375】Query on a tree【树链剖分】【或者动态树,那样常数就完了T_T】
- SPOJ375——Query on a tree(树链剖分模板详解以及入门)
- Java Dom解析xml
- java泛型边界深入探讨,示例代码
- 3d游戏基本结构设计
- 简单的数据库课程设计----湖工大成绩管理系统
- 1.准备工作
- spoj375 Query on a tree 树链剖分
- Java集合01----ArrayList的遍历方式及应用
- 易信的差异化,送给来往
- cocos2dX UI控件之CCLabelTTF
- VC内存泄露检查工具:VisualLeakDetector
- 黑马程序员--基础加强部分
- [Cocos2d-x v3.x]cocos2d::Value
- 游戏开发图片格式选择
- 编写高质量代码——“零星”总结