代码不过样例蒟蒻求调

P3384 【模板】重链剖分/树链剖分

CC__DIAMOND @ 2024-07-16 18:21:50

#include <bits/stdc++.h>
#define BAR cout<<"*******\n";
#define fst first
#define snd second
#define INFILE(x) freopen(x,"r",stdin)
#define OUTFILE(x) freopen(x,"w",stdout)
#define eb_ emplace_back
#define ep_ emplace
#define mp_ make_pair
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define ADD(x,y) ((x+y)%mod)
#define SUB(x,y) ((x-y+mod)%mod)
using namespace std;
using ll=long long;
using ul=unsigned long long;
using ui=unsigned int;
using db=double;
using pii=pair<int,int>;
using pil=pair<int,ll>;
using pll=pair<ll,ll>;
constexpr int int_inf=0x3f3f3f3f;
constexpr ll ll_inf=0x3f3f3f3f3f3f3f3fll;

namespace Solution {
    constexpr int N=1e5+10;
    ll mod;
    struct BIT {
        int n;
        ll val[N];
        void init() {
            n=0;
            memset(val,0,sizeof(val));
        }
        void add(int x,ll v) {
            for(;x<=n;x+=x&(-x)) val[x]=ADD(val[x],v);
        }
        ll query(int x) {
            ll res=0;
            for(;x;x-=x&(-x)) res=ADD(res,val[x]);
            return res;
        }
    };
    struct {
        BIT d1,d2;
        void init(ll src[],int n) {
            d1.init();
            d2.init();
            d1.n=d2.n=n;
            for(int i=1;i<=n;++i) {
                d1.add(i,src[i]);
                d2.add(i,i*src[i]%mod);
            }
        }
        void add(int x,ll v) {
            d1.add(x,v);
            d2.add(x,x*v%mod);
            d1.add(x+1,mod-v);
            d2.add(x+1,mod-(x+1)*v%mod);
        }
        void add(int l,int r,ll v) {
            d1.add(l,v);
            d1.add(r+1,mod-v);
            d2.add(l,l*v%mod);
            d2.add(r+1,mod-(r+1)*v%mod);
        }
        ll query(int x) {
            ll res=0;
            res=ADD(res,(x+1)*d1.query(x));
            res=SUB(res,d2.query(x));
            return res;
        }
        ll query(int l,int r) {
            return SUB(query(r),query(l-1));
        }
    } vals;
    vector<int> graph[N];
    int fa[N],son[N],size[N],dep[N];
    int id,dfn[N],top[N],bottom[N];
    int rnk[N];
    void dfs1(int s,int from) {
        fa[s]=from;
        size[s]=1;
        dep[s]=dep[from]+1;
        for(int ed: graph[s]) {
            if(ed==from) continue;
            dfs1(ed,s);
            size[s]+=size[ed];
            if(size[ed]>size[son[s]]) son[s]=ed;
        }
    }
    void dfs2(int s,int currtop) {
        top[s]=currtop;
        dfn[s]=++id;
        bottom[s]=dfn[s];
        rnk[id]=s;
        if(!son[s]) return;
        dfs2(son[s],currtop);
        int last=son[s];
        for(int ed: graph[s]) {
            if(ed==fa[s]||ed==son[s]) continue;
            dfs2(ed,ed);
            last=ed;
        }
        bottom[s]=bottom[last];
    }
    void add1(int x,int y,ll v) {
        while(top[x]!=top[y]) {
            if(dep[top[x]]>dep[top[y]]) swap(x,y);
            vals.add(dfn[top[y]],dfn[y],v);
            y=fa[top[y]];
        }
        if(dep[top[x]]>dep[top[y]]) swap(x,y);
        vals.add(dfn[x],dfn[y],v);
    }
    void add2(int x,ll v) {
        vals.add(dfn[x],bottom[x],v);
    }
    ll query1(int x,int y) {
        ll res=0;
        while(top[x]!=top[y]) {
            if(dep[top[x]]>dep[top[y]]) swap(x,y);
            res=ADD(res,vals.query(dfn[top[y]],dfn[y]));
            y=fa[top[y]];
        }
        if(dep[top[x]]>dep[top[y]]) swap(x,y);
        res=ADD(res,vals.query(dfn[x],dfn[y]));
        return res;
    }
    ll query2(int x) {
        return vals.query(dfn[x],bottom[x]);
    }
    ll v[N];
    void solve() {
        int n,m,r,p;
        cin>>n>>m>>r>>mod;
        for(int i=1;i<=n;++i) {
            cin>>v[i];
        }
        for(int i=1;i<n;++i) {
            int u,v;
            cin>>u>>v;
            graph[u].eb_(v);
            graph[v].eb_(u);
        }
        dfs1(r,0);
        dfs2(r,r);
        vals.d1.n=n;
        vals.d2.n=n;
        for(int i=1;i<=n;++i) {
            vals.add(dfn[i],v[i]);
        }
        for(int i=1;i<=m;++i) {
            int op,x,y;
            ll z;
            cin>>op;
            switch(op) {
                case 1:
                    cin>>x>>y>>z;
                    add1(x,y,z);
                    break;
                case 2:
                    cin>>x>>y;
                    cout<<query1(x,y)<<'\n';
                    break;
                case 3:
                    cin>>x>>z;
                    add2(x,z);
                    break;
                case 4:
                    cin>>x;
                    cout<<query2(x)<<'\n';
                    break;
                default:
                    break;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int T=1;
    // cin>>T;
    while(T--) {
        Solution::solve();
    }
    return 0;
}

by M1saka16I72 @ 2024-07-16 18:57:52

会这么多科技/bx


|