树链剖分模板

来源:互联网 发布: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 ;}

原创粉丝点击