Spoj375 Query on a tree 裸·树链剖分
2016-08-08 20:36
513 查看
题意:
边修改,树上最值查询
分析:
又裸又水,略
代码:
边修改,树上最值查询
分析:
又裸又水,略
代码:
#include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 100000 + 10; void read(int &n) { int f = 1; n = 0; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >='0' && ch <='9') { n = n * 10 + ch - 48; ch = getchar(); } n *= f; } struct SegmentTree { int Max[maxn * 4]; void init() { memset(Max, 0, sizeof(Max)); } void Push_up(int u) { int lc = u << 1, rc = u << 1 | 1; Max[u] = max(Max[lc], Max[rc]); } void update(int u, int l, int r, int sl, int sr, int v) { if(sl <= l && r <= sr) { Max[u] = v; return; } int mid = (l + r) >> 1, lc = u << 1, rc = u << 1 | 1; if(sl <= mid) update(lc, l, mid, sl, sr, v); if(sr > mid) update(rc, mid+1, r, sl, sr, v); Push_up(u); } int query(int u, int l, int r, int sl, int sr) { if(sl <= l && r <= sr) return Max[u]; int Tmp = -INF; int mid = (l + r) >> 1, lc = u << 1, rc = u << 1 | 1; if(sl <= mid) Tmp = max(Tmp, query(lc, l, mid, sl, sr)); if(sr > mid) Tmp = max(Tmp, query(rc, mid+1, r, sl, sr)); return Tmp; } }ST; struct Edge { int from, to, dist; }e[maxn]; int Begin[maxn], Next[maxn*2], To[maxn*2], E; void Add(int x, int y) { To[++E] = y; Next[E] = Begin[x]; Begin[x] = E; } int cnt, n; int tid[maxn], son[maxn], top[maxn], fa[maxn], size[maxn], dep[maxn]; void dfs(int cur, int f, int d) { dep[cur] = d; size[cur] = 1; for(int i=Begin[cur]; i; i=Next[i]) { int t = To[i]; if(t != f) { dfs(t, cur, d+1); fa[t] = cur; size[cur] += size[t]; if(son[cur] == -1 || size[t] > size[son[cur]]) son[cur] = t; } } } void dfs(int cur, int tp) { top[cur] = tp; tid[cur] = ++cnt; if(son[cur] == -1) return; dfs(son[cur], tp); for(int i=Begin[cur]; i; i=Next[i]) { int t = To[i]; if(t != fa[cur] && t != son[cur]) dfs(t, t); } } void init() { E = cnt = 0; ST.init(); memset(fa, 0, sizeof(fa)); memset(son, -1, sizeof(son)); memset(Begin, 0, sizeof(Begin)); for(int i=1; i<n; i++) { scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].dist); Add(e[i].from, e[i].to); Add(e[i].to, e[i].from); } dfs(1, 1, 1); dfs(1, 1); for(int i=1; i<n; i++) { if(dep[e[i].to] < dep[e[i].from]) swap(e[i].to, e[i].from); ST.update(1, 2, cnt, tid[e[i].to], tid[e[i].to], e[i].dist); } } int Getmax(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, ST.query(1, 2, cnt, tid[top[x]], tid[x])); x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x, y); if(x != y) ans = max(ans, ST.query(1, 2, cnt, tid[x]+1, tid[y])); return ans; } char s[20]; int T, u, v; int main() { #ifndef ONLINE_JUDGE freopen(" 4000 data.txt", "r", stdin); freopen("ans.txt", "w", stdout); #endif read(T); while(T--) { read(n); init(); while(scanf("%s", s) == 1 && s[0] != 'D') { read(u), read(v); if(s[0] == 'C') ST.update(1, 2, cnt, tid[e[u].to], tid[e[u].to], v); else printf("%d\n", Getmax(u, v)); } } return 0; }
相关文章推荐
- SPOJ375 Query on a tree(树链剖分)
- SPOJ 375 Query on a tree[树链剖分入门]
- SPOJ 375 Query on a tree【树链剖分】
- spoj375 Query on a tree(树链剖分 边权 入门题)
- 【树链剖分】spoj375 Query on a tree
- spoj 375 QTREE - Query on a tree 树链剖分 LCT 动态树
- 【树链剖分】SPOJ 375 Query on a tree 裸题
- SPOJ 375 Query on a tree(树链剖分)
- 【spoj375】Query on a tree【树链剖分】【或者动态树,那样常数就完了T_T】
- spoj 375 Query on a tree(树链剖分,线段树)
- spoj 375 Query on a tree(树链剖分,边,线段树)
- SPOJ-375 QTREE - Query on a tree (树链剖分 边权转点权)
- SPOJ 375 Query on a tree(初学树链剖分)
- 树链剖分 spoj 375 Query on a tree(剖分入门)
- 【SPOJ】375 Query on a tree QTREE系列之1 树链剖分
- SPOJ 375 树链剖分 QTREE - Query on a tree
- spoj 375 Query on a tree(树链剖分模版)
- spoj 375 Query on a tree 树链剖分
- spoj 375 QTREE - Query on a tree(树链剖分,边权)
- spoj 375 Query on a tree 树链剖分