zoukankan      html  css  js  c++  java
  • 模板——树链剖分

    放个板子而已。。

    #include<stdio.h>
    #include<algorithm>
    #define ls root<<1
    #define rs root<<1|1
    using namespace std;
    typedef long long ll;
    
    int n,m,r;ll res,p;
    
    const int MAXN = 100005;
    ll a[MAXN];
    struct edge{
        int v,nxt;
    }e[MAXN<<1];
    
    struct TREE{
        int lazy,l,r,val;
    }tree[MAXN*4];
    int head[MAXN];int cnt=0;int dep[MAXN];int fa[MAXN];int son[MAXN];int size[MAXN];int top[MAXN];int newval[MAXN];int id[MAXN];
    int tot=0;
    
    inline void add(int u,int v){
        e[++cnt].v = v;e[cnt].nxt = head[u];head[u] = cnt;
    }
    
    inline void pushdown(int root,int len){
        tree[ls].lazy += tree[root].lazy;
        tree[rs].lazy += tree[root].lazy;
        tree[ls].val += tree[root].lazy * (len-(len>>1));
        tree[rs].val += tree[root].lazy * (len>>1);
        tree[ls].val %= p;
        tree[rs].val %= p;
        tree[root].lazy = 0;
    }
    
    inline void update(int root,int L,int R,int l,int r,ll k){
        if(l <= L && R <= r){
            tree[root].lazy += k;
            tree[root].val += (R-L+1)*k;
        }
        else{
            int mid = (L + R) >> 1;
            if(tree[root].lazy) pushdown(root,R-L+1);
            if(l <= mid) update(ls,L,mid,l,r,k);
            if(r >= mid+1) update(rs,mid+1,R,l,r,k);
            tree[root].val = tree[ls].val + tree[rs].val;
            tree[root].val %= p;
        }
    }
    
    inline void query(int root,int L,int R,int l,int r){
        if(l <= L && R <= r){
            res += tree[root].val;
            res %= p;
            return ;
        }
        else{
            int mid = (L + R) >> 1;
            if(tree[root].lazy) pushdown(root,R-L+1);
            if(l <= mid) query(ls,L,mid,l,r);
            if(r >= mid+1) query(rs,mid+1,R,l,r);
        }
    }
    
    //////////////////////////线段树分割线////////////////////////////////////
    
    inline void dfs1(int root,int father,int depth){
        dep[root] = depth;
        fa[root] = father;
        size[root] = 1;
        for(int i=head[root];i;i=e[i].nxt){
            int v = e[i].v;
            if(v == father) continue;
            dfs1(v,root,depth+1);
            size[root] += size[v];
            if(!son[root] || size[v] > size[son[root]]){
                son[root] = v;
            }
        }
    }
    
    inline void dfs2(int u,int nowtop){
        id[u] = ++tot;
        top[u] = nowtop;
        newval[tot] = a[u];
        if(!son[u]) return ;
        dfs2(son[u] , nowtop);
        for(int i=head[u];i;i=e[i].nxt){
            int v = e[i].v;
            if(v == fa[u] || v == son[u]) continue;
            dfs2(v,v);
        }
    }
    
    inline void build(int root,int l,int r){
        if(l == r){
            tree[root].val = newval[l];
            tree[root].val %= p;
            return ;
        }
        int mid = (l + r) >> 1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        tree[root].val = tree[ls].val + tree[rs].val;
        tree[root].val %= p;
    }
    
    inline void addrange(int l,int r,ll num){
        while(top[l] ^ top[r]){
            if(dep[top[l]] < dep[top[r]]) swap(l,r);
            update(1,1,n,id[top[l]],id[l],num);
            l = fa[top[l]];
        }
        if(dep[l] > dep[r]) swap(l,r);
        update(1,1,n,id[l],id[r],num);
    }
    
    inline int queryrange(int l,int r){
        int ans = 0;
        while(top[l] ^ top[r]){
            if(dep[top[l]] < dep[top[r]]) swap(l,r);
            res=0;
            query(1,1,n,id[top[l]],id[l]);
            ans += res;
            ans %= p;
            l = fa[top[l]];
        }
        if(dep[l] > dep[r]) swap(l,r);
        res=0;
        query(1,1,n,id[l],id[r]);
        ans += res;
        return ans%p;
    }
    
    int main(){
        scanf("%d%d%d%lld",&n,&m,&r,&p);
        for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
        for(int i=1;i<n;++i){
            int u,v;scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        dfs1(r,0,1);
        dfs2(r,r);
        build(1,1,n);
        for(;m;--m){
            int k;scanf("%d",&k);
            switch (k){
                case 1:{
                    int x,y;ll z;
                    scanf("%d%d%lld",&x,&y,&z);
                    z %= p;
                    addrange(x,y,z);
                    break;
                }
                case 2:{
                    int x,y;
                    scanf("%d%d",&x,&y);
                    printf("%d
    ",queryrange(x,y));
                    break;
                }
                case 3:{
                    int x;ll z;
                    scanf("%d%lld",&x,&z);
                    update(1,1,n,id[x],id[x]+size[x]-1,z);
                    break;
                }
                case 4:{
                    int x;scanf("%d",&x);
                    res = 0;
                    query(1,1,n,id[x],id[x]+size[x]-1);
                    printf("%lld
    ",res%p);
                    break;
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    多层结构中,事务的运用。
    A private conversation
    Sql Server 日志清理 (数据库压缩方法)
    Basic of Ajax
    Persin Buttons
    不知为什么无缘无故加到了一个“邯郸.net俱乐部”,想退出,找不到入口.....
    Wokflow designer not working when openning workflow in nonworkflow VS 2005 project
    GridView中如何取得隐藏列的值?
    Error: cannot obtain value
    Too late
  • 原文地址:https://www.cnblogs.com/lajioj/p/9479056.html
Copyright © 2011-2022 走看看