大佬求救,被T傻了,只能过两个点 orz
查看原帖
大佬求救,被T傻了,只能过两个点 orz
265978
Retired楼主2021/9/22 22:58
#include<bits/stdc++.h>
using namespace  std;
const int N=1e5+10;
typedef long long ll;
int n,m,h[N],ne[N*2],e[N*2],idx;
int w[N],nw[N];
int cnt,dfn[N];
int top[N];
int dep[N],fa[N],son[N],sz[N],mod;
int root;
struct Node
{
    int l,r;
    int sum,add;
    #define ls p<<1
    #define rs p<<1|1
}t[N*4];

void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void pushdown(int p)
{
    if(t[p].add){
        
        t[ls].sum=(t[ls].sum+(ll)(t[ls].r-t[ls].l+1)*t[p].add)%mod;
        t[rs].sum=(t[rs].sum+(ll)(t[rs].r-t[rs].l+1)*t[p].add)%mod;
        t[ls].add+=t[p].add;
        t[rs].add+=t[p].add;
        // t[ls].add=(t[ls].add+t[p].add)%mod;
        // t[rs].add=(t[rs].add+t[p].add)%mod;
        t[p].add=0;
    }
}

void pushup(int p){
    t[p].sum=t[ls].sum+t[rs].sum;
}

void build(int p,int l,int r)
{
    t[p]={l,r};
    if(l==r){
        t[p].sum=nw[l];
        return ;
    }
    int mid=l+r>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(p);
}

void modify(int p,int tl,int tr,int k)
{
    if(tl<=t[p].l&&t[p].r<=tr){
        t[p].sum=(t[p].sum+(ll)(t[p].r-t[p].l+1)*k)%mod;
        // t[p].add=(t[p].add+k)%mod;
        t[p].add+=k;
        return ;
    }
    pushdown(p);
    int mid=t[p].l+t[p].r>>1;
    if(tl<=mid){
        modify(ls,tl,tr,k);
    }
    if(tr>mid){
        modify(rs,tl,tr,k);
    }
    pushup(p);
}

int query(int p,int tl,int tr)
{
    if(tl<=t[p].l&&t[p].r<=tr){
        return t[p].sum;
    }
    pushdown(p);
    int res=0;
    int mid=t[p].l+t[p].r>>1;
    if(tl<=mid){
        res=query(ls,tl,tr);
    }
    if(tr>mid){
        res=(res+query(rs,tl,tr))%mod;
    }
    return res%mod;
}

void dfs_2(int u,int t)
{
    dfn[u]=++cnt,nw[cnt]=w[u],top[u]=t;
    if(!son[u])return;
    dfs_2(son[u],t);
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        if(j==fa[u]||j==son[u])continue;
        dfs_2(j,j);
    }
}

void dfs_1(int u,int father,int depth)
{
    sz[u]=1,fa[u]=father,dep[u]=depth;
    for(int i=h[u];~i;i=ne[i])
    {
        int j=e[i];
        if(j==father)continue;
        dfs_1(j,u,depth+1);
        sz[u]+=sz[j];
        if(sz[son[u]]<sz[j]){
            son[u]=j;//
        }
    }
}

void update_path(int u,int v,int k)
{
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        modify(1,dfn[top[u]],dfn[u],k);
        u=fa[top[u]];
    }
    if(dep[u]<dep[v])swap(u,v);
    modify(1,dfn[v],dfn[u],k);
}

int query_path(int u,int v)
{
    int res=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]])swap(u,v);
        res=(res+query(1,dfn[top[u]],dfn[u]))%mod;    
        u=fa[top[u]];
    }
    if(dep[u]<dep[v])swap(u,v);
    res=(res+query(1,dfn[v],dfn[u]))%mod;
    return  res%mod;
}

int main()
{
    scanf("%d%d%d%d",&n,&m,&root,&mod);
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    
    for(int i=0;i<n-1;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);add(b,a);
    }
    
    dfs_1(root,-1,1);
    dfs_2(root,1);
    build(1,1,n);
    while(m--){
        int t,k,u,v;
        scanf("%d%d",&t,&u);
        if(t==1){
            scanf("%d%d",&v,&k);
            update_path(u,v,k);
        }
        else if(t==3){
            scanf("%d",&k);
            modify(1,dfn[u],dfn[u]+sz[u]-1,k);
        }
        else if(t==2){
            scanf("%d",&v);
            printf("%d\n",query_path(u,v)%mod);
        }
        else{
            printf("%d\n",query(1,dfn[u],dfn[u]+sz[u]-1)%mod);
            // cout<<query(1,dfn[u],dfn[u]+sz[u]-1)<<endl;
        }
    }
    return 0; 
}
2021/9/22 22:58
加载中...