树链剖分模板
来源:互联网 发布:ubuntu软件无图标 编辑:程序博客网 时间:2024/06/05 10:22
样题链接
http://www.spoj.com/problems/QTREE/
模板如下:
#include <bits/stdc++.h>using namespace std ;typedef long long ll ;const int maxn = 1e4 + 5 ;int deep[maxn] ;int size[maxn] ;int father[maxn] ;int son[maxn] ;int id[maxn] ;int value[maxn] ;int top[maxn] ;int num ;vector<int> point[maxn] ;struct edge{ int st , ed , val ;};edge save[maxn] ;void dfs_first(int u , int fa , int dp){ deep[u] = dp ; size[u] = 1 ; son[u] = 0 ; father[u] = fa ; for(int i = 0 ; i < point[u].size() ; i ++ ){ int ed = point[u][i] ; if(fa == ed) continue ; dfs_first(ed , u , dp + 1) ; size[u] += size[ed] ; if(size[ son[u] ] < size[ed]) son[u] = ed ; }}void dfs_second(int u , int temp){ top[u] = temp ; id[u] = ++ num ; if(son[u]) dfs_second(son[u] , temp) ; for(int i = 0 ; i < point[u].size() ; i ++ ){ int ed = point[u][i] ; if(ed == father[u] || ed == son[u]) continue ; dfs_second(ed , ed) ; }}void init(int n ){ for(int i = 1 ; i <= n ; i ++ ) point[i].clear() ; num = 0 ;}/// make treestruct Tree{ int l , r , val ;};Tree tree[maxn * 4] ;void push_up(int node){ tree[node].val = max(tree[node<<1].val , tree[node<<1|1].val) ;}void build(int l , int r , int node) { tree[node].l = l ; tree[node].r = r ; if(l == r){ tree[node].val = value[l] ; return ; } int mid = (l + r) >> 1 ; build(l , mid , node << 1) ; build(mid + 1 , r , node << 1 | 1) ; push_up(node) ;}void update(int node , int pos , int val){ if(tree[node].l == tree[node].r){ tree[node].val = val ; return ; } int mid = (tree[node].l + tree[node].r) >> 1 ; if(pos <= mid) update(node << 1 , pos , val) ; else update(node << 1 | 1 , pos , val) ; push_up(node) ;}int query(int node , int l , int r){ if(tree[node].l > r || tree[node].r < l) return 0 ; if(tree[node].l >= l && tree[node].r <= r) return tree[node].val ; int ans = 0 ; int mid = (tree[node].l + tree[node].r) >> 1 ; if(l <= mid) ans = max(ans , query(node << 1 , l , r)) ; if(r > mid) ans = max(ans , query(node << 1 | 1 , l , r )) ; return ans ;}int work(int u , int v){ int top_u = top[u] , top_v = top[v] ; int ans = 0 ; while(top_u != top_v){ if(deep[top_u] < deep[top_v]){ swap(top_u , top_v) ; swap(u , v) ; } ans = max(query(1 , id[top_u] , id[u]) , ans) ; u = father[top_u] ; top_u = top[u] ; } if(u == v) return ans ; if(deep[u] > deep[v]) swap(u , v) ; ans = max(ans , query(1 , id[son[u]] , id[v])) ; return ans ;}/*131 2 22 3 1*/int main(){ int kase ; scanf("%d" , &kase) ; int a , b , w ; while( kase -- ){ int n ; scanf("%d" , &n) ; init(n) ; for(int i = 1 ; i < n ; i ++ ){ scanf("%d %d %d" , &save[i].st , &save[i].ed , &save[i].val) ; a = save[i].st , b = save[i].ed ; point[a].push_back(b) ; point[b].push_back(a) ; } dfs_first(1 , 0 , 1) ; dfs_second(1 , 1) ; for(int i = 1 ; i < n ; i ++ ){ a = save[i].st , b = save[i].ed , w = save[i].val ; if(deep[a] < deep[b]) swap(save[i].st , save[i].ed) ; value[ id[ save[i].st ] ] = w ; } build(1 , num , 1) ; char read[20] ; while(~ scanf("%s" , read)){ if(read[0] == 'D') break ; scanf("%d %d" , &a , &b) ; if(read[0] == 'Q') printf("%d\n" , work(a , b)) ; else update(1 , id[save[a].st] , b) ; } } return 0 ;}
阅读全文
0 0
- 树链剖分 模板
- 模板-树链剖分
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 【模板】树链剖分
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分模板
- 树链剖分 模板
- 【模板】树链剖分
- Java设计模式之代理模式(1)
- 公约数的个数
- LRU Cache
- 算法爱好者——下一个稀疏数 ? 待解决
- C语言求字符串是否是回文
- 树链剖分模板
- A. Carrot Cakes Codeforce 思维
- CodeForces
- 算法爱好者——编辑距离? 待解决
- sorted函数
- Python_cmd的各种实现方法及优劣(os.system, subprocess.Popen和commands.getstatusoutput)
- Mongodb 自动增长 自增id 实现
- BZOJ1816(Cqoi2010)[扑克牌]--二分答案
- 九周九分布式服务-架构演进