码迷,mamicode.com
首页 > 其他好文 > 详细

存板子专用

时间:2019-02-17 20:44:38      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:img   style   root   struct   fine   swa   date   line   else   

某谷树剖模板

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigend long long
#define rep(k,i,j) for(int k = i;k <= j; ++k)
#define FOR(k,i,j) for(int k = i;k >= j; --k)
inline int read(){
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=(x<<1)+(x<<3)+ch-0; ch=getchar();}
    return x*f;
}
const int mxn = 2e5+10;
int n,m,root,p;
int tp[mxn],fa[mxn],id[mxn],val[mxn],dep[mxn],sz[mxn],link[mxn],son[mxn];
struct edge{int nxt,y;}e[mxn<<1];
struct Tree{int l,r,tag,sum;}tree[mxn<<2];
int len,to[mxn];
int res = 0,cnt;
inline void add(int xx,int yy){
    e[++len].nxt = to[xx];
    to[xx] = len;
    e[len].y = yy;
}
inline void pushdown(int pos,int lth){
    int tag_ = tree[pos].tag;
    if(tag_){
        tree[pos<<1].tag += tag_;
        tree[pos<<1|1].tag += tag_;
        tree[pos<<1].sum += tag_*(lth-(lth>>1));
        tree[pos<<1|1].sum += tag_*(lth>>1);
        tree[pos<<1].sum %= p;
        tree[pos<<1|1].sum %= p;
        tree[pos].tag = 0;
    }
}
inline void build(int pos,int l,int r){
    if(l==r){
        tree[pos].sum = link[l];
        if(tree[pos].sum > p) tree[pos].sum %= p;
        return;
    }
    int m = l+r >>1;
    build(pos<<1,l,m),build(pos<<1|1,m+1,r);
    tree[pos].sum = (tree[pos<<1].sum + tree[pos<<1|1].sum)%p;
}
inline void query(int pos,int lp,int rp,int l,int r){
    if(l<=lp&&rp<=r){
        res += tree[pos].sum;
        res %= p;
        return;
    }else{
    pushdown(pos,rp-lp+1);
    int m = lp+rp >>1;
    if(l<=m) query(pos<<1,lp,m,l,r);
    if(r>m) query(pos<<1|1,m+1,rp,l,r);
    }
}
inline void update(int pos,int lp,int rp,int l,int r,int k){
    if(l<=lp&&rp<=r){
        tree[pos].tag += k;
        tree[pos].sum += k*(rp-lp+1);
        return;
    }
    pushdown(pos,rp-lp+1);
    int m = lp+rp >>1;
    if(l<=m) update(pos<<1,lp,m,l,r,k);
    if(r>m) update(pos<<1|1,m+1,rp,l,r,k);
    tree[pos].sum = (tree[pos<<1].sum+tree[pos<<1|1].sum)%p;
}
inline int query_2(int x,int y){
    int ans = 0;
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
        res = 0;
        query(1,1,n,id[tp[x]],id[x]);
        ans += res;
        ans %= p;
        x = fa[tp[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    res = 0;
    query(1,1,n,id[x],id[y]);
    ans += res;
    return ans%p;
}
inline void update_1(int x,int y,int k){
    k %= p;
    while(tp[x]!=tp[y]){
        if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
        update(1,1,n,id[tp[x]],id[x],k);
        x = fa[tp[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(1,1,n,id[x],id[y],k);
}
inline int query_4(int x){
    res = 0;
    query(1,1,n,id[x],id[x]+sz[x]-1);
    return res;
}
inline void update_3(int x,int k){
    update(1,1,n,id[x],id[x]+sz[x]-1,k);
}
inline void dfs1(int x,int f,int d){
    dep[x] = d,fa[x] = f;
    sz[x] = 1;
    int maxson = -1;
    for(int i = to[x]; i;i = e[i].nxt){
        int y = e[i].y;
        if(y==f) continue;
        dfs1(y,x,d+1);
        sz[x] += sz[y];
        if(sz[y]>maxson) son[x] = y,maxson = sz[y];
    }
}
inline void dfs2(int x,int topf){
    id[x] = ++cnt;
    link[cnt] = val[x];
    tp[x] = topf;
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(int i = to[x]; i;i = e[i].nxt){
        int y = e[i].y;
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y,y);
    }
}
int main(){
    n = read(),m = read(),root = read(),p = read();
    rep(i,1,n) val[i] = read();
    rep(i,1,n-1){
        int x = read(),y = read();
        add(x,y),add(y,x);
    }    
    dfs1(root,0,1);
    dfs2(root,root);
    build(1,1,n);
    while(m--){
        int opt,x,y,z;
        opt = read();
        if(opt==1){
            x = read(),y = read(),z = read();
            update_1(x,y,z);
        }else if(opt==2){
            x = read(),y = read();
            printf("%d\n",query_2(x,y));
        }else if(opt==3){
            x = read(),y = read();
            update_3(x,y);
        }else{
            x = read();
            printf("%d\n",query_4(x));
        }
    }
}
View Code

 

存板子专用

标签:img   style   root   struct   fine   swa   date   line   else   

原文地址:https://www.cnblogs.com/ve-2021/p/10392362.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!