27pts only AC #1#2#3 求调 玄关
查看原帖
27pts only AC #1#2#3 求调 玄关
1771965
tuxiaolai楼主2025/8/3 11:38
#include<bits/stdc++.h>
using namespace std;
int n,m,r,mod;
int u,v;
int op,x,y,z;
vector<int> adj[100010],son[100010];
vector<long long> a;
int b[100010];
bool vis[100010];
int des[100010],deep[100010],dss[100010];
int hld[100010],hfa[100010],hff[100010];
int k;
bool cmpdes(int a,int b) {
    return des[a]>des[b];
}
int dfs1(int p) {
    int res=1;
    for(int i:adj[p]) {
        if(vis[i]) {
            continue;
        }
        vis[i]=1;
        son[p].push_back(i);
        res+=dfs1(i);
    }
    return des[p]=res;
}
void HLD(int p,int fa) {
    //cerr<<"HLD:"<<p<<" ok!!!\n";//c
    if(p==r) {
        hff[1]=1;
    }
    hld[p]=++k;
    a.push_back(b[p]);
    hfa[k]=hld[fa];
    //cerr<<p<<':'<<" hld:"<<hld[p]<<" hfa:"<<hfa[k]<<'\n';//c
    sort(son[p].begin(),son[p].end(),cmpdes);
    for(int i=0; i<son[p].size(); i++) {
        if(i==0) {
            HLD(son[p][i],fa);
        } else {
            hff[k+1]=hld[p];
            //cout<<k+1<<" hff:"<<hld[p]<<'\n';//c
            HLD(son[p][i],son[p][i]);
        }
    }
    return ;
}
int dfs2(int p,int d) {
    int res=hld[p];
    deep[hld[p]]=d;
    for(int i:son[p]) {
        res=max(res,dfs2(i,d+1));
    }
    return dss[hld[p]]=res;
}
//Segtree
struct Segtree {
    int n;
    vector<long long> tree,lazy;
    void init(int size,vector<long long> &a) {
        n=size;
        tree.resize(4*n+10);
        lazy.resize(4*n+10);
        build(1,1,n,a);
    }
    void build(int p,int l,int r,vector<long long> &a) {
        if(l==r) {
            tree[p]=a[l-1];
            return;
        }
        int mid=(l+r)/2;
        build(p*2,l,mid,a);
        build(p*2+1,mid+1,r,a);
        tree[p]=(tree[p*2]+tree[p*2+1])%mod;
    }
    void pushdown(int p,int l,int r) {
        if(lazy[p]) {
            int mid=(l+r)/2;
            tree[p*2]+=(mid-l+1)*lazy[p];
            tree[p*2]%=mod;
            tree[p*2+1]+=(r-mid)*lazy[p];
            tree[p*2+1]%=mod;
            lazy[p*2]+=lazy[p];
            lazy[p*2]%=mod;
            lazy[p*2+1]+=lazy[p];
            lazy[p*2+1]%=mod;
            lazy[p]=0;
        }
    }
    void add(int p,int l,int r,int ql,int qr,long long val) {
        if(ql<=l && r<=qr) {
            tree[p]+=(r-l+1)*val;
            tree[p]%=mod;
            lazy[p]+=val;
            lazy[p]%=mod;
            return;
        }
        pushdown(p,l,r);
        int mid=(l+r)/2;
        if(mid>=ql) {
            add(p*2,l,mid,ql,qr,val);
        }
        if(mid+1<=qr) {
            add(p*2+1,mid+1,r,ql,qr,val);
        }
        tree[p]=(tree[p*2]+tree[p*2+1])%mod;
    }
    long long query(int p,int l,int r,int ql,int qr) {
        if(ql<=l && r<=qr) {
            return tree[p];
        }
        pushdown(p,l,r);
        int mid=(l+r)/2;
        long long res=0;
        if(mid>=ql) {
            res+=query(p*2,l,mid,ql,qr);
            res%=mod;
        }
        if(mid+1<=qr) {
            res+=query(p*2+1,mid+1,r,ql,qr);
            res%=mod;
        }
        return res;
    }
} tree;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("/storage/emulated/0/txlpy/CPPProject/默认目录/Helloworld/src/infile.txt","r",stdin);//t
    cin>>n>>m>>r>>mod;
    for(int i=1; i<=n; i++) {
        cin>>b[i];
    }
    for(int i=1; i<n; i++) {
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    vis[r]=1;
    dfs1(r);
    //cerr<<"dfs1 ok!!!\n";//c
    HLD(r,r);
    //cerr<<"HLD ok!!!\n";//c
    dfs2(r,1);
    //cerr<<"dfs2 ok!!!\n";//c
    tree.init(n,a);
    //cerr<<"init ok!!!\n";//c
    for(int i=1; i<=m; i++) {
        cin>>op;
        if(op==1) {
            cin>>x>>y>>z;
            x=hld[x];
            y=hld[y];
            while(hfa[x]!=hfa[y]) {
                if(deep[hfa[x]]<deep[hfa[y]]) {
                    swap(x,y);
                }
                tree.add(1,1,n,x,hfa[x],z);
                x=hff[hfa[x]];
                //cout<<x<<'~'<<hfa[x]<<" +="<<z<<'\n';//c
            }
            tree.add(1,1,n,min(x,y),max(x,y),z);
        }
        if(op==2) {
            long long tot=0;
            cin>>x>>y;
            x=hld[x];
            y=hld[y];
            while(hfa[x]!=hfa[y]) {
                if(deep[hfa[x]]<deep[hfa[y]]) {
                    swap(x,y);
                }
                tot+=tree.query(1,1,n,x,hfa[x]);
                tot%=mod;
                x=hff[hfa[x]];
            }
            tot+=tree.query(1,1,n,min(x,y),max(x,y));
            cout<<tot%mod<<'\n';
        }
        if(op==3) {
            cin>>x>>z;
            x=hld[x];
            tree.add(1,1,n,x,dss[x],z);
        }
        if(op==4) {
            cin>>x;
            x=hld[x];
            cout<<tree.query(1,1,n,x,dss[x])<<'\n';
        }
    }
    return 0;
}
2025/8/3 11:38
加载中...