模板汇总——树剖

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 1e5 + 100;
const int M = N<<1;
struct Tree{
    int head[N], to[M], nt[M];
    int sz[N], son[N], deep[N], top[N], fa[N], dfn[N], dto[N];
    int tr[N<<2], lz[N<<2], sum[N<<2];
    int a[N];
    int tot, dtot;
    int n;
    void add(int u, int v){
        to[tot] = v; nt[tot] = head[u]; head[u] = tot++;
        to[tot] = u; nt[tot] = head[v]; head[v] = tot++;
    }
    void dfs1(int o, int u){
        sz[u] = 1;
        for(int i = head[u]; ~i; i = nt[i]){
            int v = to[i];
            if(v == o) continue;
            dfs1(u, v);
            if(sz[v] > sz[son[u]]) son[u] = v;
            sz[u] += sz[v];
        }
    }
    void dfs2(int o, int u, int t){
        deep[u] = deep[o] + 1;
        top[u] = t;
        fa[u] = o;
        dfn[u] = ++dtot;
        dto[dtot] = u;
        if(son[u]) dfs2(u, son[u], t);
        for(int i = head[u]; ~i; i = nt[i]){
            int v = to[i];
            if(v == o || v == son[u]) continue;
            dfs2(u, v, v);
        }
    }
    void PushUp(int rt){
        sum[rt] = sum[rt<<1|1] + sum[rt<<1];
        return ;
    }
    void PushDown(int rt){
        return ;
    }
    void Build(int l, int r,int rt){
        if(l == r){
            tr[rt] = a[dto[l]];
            return ;
        }
        int m = l+r >> 1;
        Build(lson); Build(rson);
        PushUp(rt);
    }
    int Query_Seg(int L, int R, int l, int r, int rt){/// dfn调用
       if(L > R) return 0;
        if(L <= l && r <= R)
            return sum[rt];
        int m = l+r >> 1;
        int ret = 0;
        PushDown(rt);
        if(L <= m) ret += Query_Seg(L, R, lson);
        if(m < R) ret += Query_Seg(L, R, rson);
        return ret;
    }
    int Query_Path(int x, int y){///点调用
        int fx = top[x], fy = top[y];
        int ret = 0;
        while(fx != fy){
            if(deep[fx] > deep[fy]){
                ret += Query_Seg(dfn[fx],dfn[x],1,n,1);
                x = fa[fx]; fx = top[x];
            }
            else {
                ret += Query_Seg(dfn[fy],dfn[y],1,n,1);
                y = fa[fy]; fy = top[y];
            }
        }
        if(deep[x] < deep[y]) ret += Query_Seg(dfn[x]+1, dfn[y], 1, n, 1);
        else ret += Query_Seg(dfn[y]+1, dfn[x], 1, n,1);
        return ret;
    }
    void Updata_Seg(int L, int R, int C, int l, int r, int rt){ /// dfn调用
        if(L <= l  && r <= R){
            tr[rt] = C;
            sum[rt] = C;
            return ;
        }
        int m = l+r >> 1;
        PushDown(rt);
        if(L <= m) Updata_Seg(L, R, C, lson);
        if(m < R) Updata_Seg(L, R, C, rson);
        PushUp(rt);
        return ;
    }
    void Updata_Path(int x, int y, int c){///点调用
        int fx = top[x], fy = top[y];
        int ret = 0;
        while(fx != fy){
            if(deep[fx] > deep[fy]){
                Updata_Seg(dfn[fx], dfn[x], c, 1, n, 1);
                x = fa[fx]; fx = top[x];
            }
            else {
                Updata_Seg(dfn[fy],dfn[y],c,1,n,1);
                y = fa[fy]; fy = top[y];
            }
        }
        if(deep[x] < deep[y]) Updata_Seg(dfn[x], dfn[y], c, 1, n, 1);
        else Updata_Seg(dfn[y], dfn[x], c, 1, n,1);
    }
    int lca(int x, int y){
        int fx = top[x], fy = top[y];
        while(fx != fy){
            if(deep[fx] > deep[fy])
                x = fa[fx], fx = top[x];
            else
                y = fa[fy], fy = top[y];
        }
        if(deep[x] < deep[y]) return x;
        return y;
    }
    int caldis(int x, int y){
        return deep[x] + deep[y] - 2 * deep[lca(x,y)];
    }
    void init(int x){
        memset(head, -1, sizeof(head));
        memset(son, 0, sizeof son);
        tot = dtot = 0;
        n = x;
    };
}tree;
int main(){
    int n;
    scanf("%d", &n);
    tree.init(n);
    int u, v;
    for(int i = 1; i < n; ++i){
        scanf("%d%d", &u, &v);
        tree.add(u, v);
    }
    tree.dfs1(0, 1);
    tree.dfs2(0, 1, 1);
    tree.Build(1, n, 1);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/MingSD/p/10757465.html