代码球调/kel
查看原帖
代码球调/kel
312084
yangzd楼主2022/7/31 21:28
#include<bits/stdc++.h>
using namespace std;

const int maxn=1005;

struct edge
{
    int next,to;
}e[maxn*2];

struct node
{
    int l,r,ls,rs,sum,lazy;
}a[maxn*2];

int n,m,r,rt,mod,v[maxn],head[maxn];
int cnt,f[maxn],d[maxn],son[maxn];
int size[maxn],top[maxn],id[maxn],rk[maxn];

void add(int x,int y)
{
    e[cnt++].next=head[x];
    e[cnt].to=y;
    head[x]=cnt;
}

void dfs1(int x)
{
    size[x]=1,d[x]=d[f[x]]+1;

    for (int v,i=head[x]; i; i=e[i].next)
        if((v=e[i].to)!=f[x])
        {
            f[v]=x;
            dfs1(v);
            size[x]+=size[v];

            if (size[son[x]]<size[v])
                son[x]=v;
        }
}

void dfs2(int x,int tp)
{
    top[x]=tp;
    id[x]=cnt++;
    rk[cnt]=x;

    if (son[x])
        dfs2(son[x],tp);

    for (int v,i=head[x]; i; i=e[i].next)
        if ((v=e[i].to)!=f[x] && v!=son[x])
            dfs2(v,v);
}

inline void pushup(int x)
{
    a[x].sum=(a[a[x].ls].sum+a[a[x].rs].sum)%mod;
}

void build(int l,int r,int x)
{
    if(l==r){
        a[x].sum=v[rk[l]],a[x].l=a[x].r=l;
        return;
    }
    
    int mid=l+r>>1;
    a[x].ls=cnt++;
    a[x].rs=cnt++;
    
	build(l,mid,a[x].ls),build(mid+1,r,a[x].rs);
    
	a[x].l=a[a[x].ls].l;
    a[x].r=a[a[x].rs].r;
    pushup(x);
}

inline int len(int x)
{
    return a[x].r-a[x].l+1;
}

inline void pushdown(int x)
{
    if(a[x].lazy)
    {
        int ls=a[x].ls,rs=a[x].rs,lz=a[x].lazy;
        (a[ls].lazy+=lz)%=mod;
        (a[rs].lazy+=lz)%=mod;
        (a[ls].sum+=lz*len(ls))%=mod;
        (a[rs].sum+=lz*len(rs))%=mod;
        a[x].lazy=0;
    }
}

void update(int l,int r,int c,int x)
{
    if(a[x].l>=l && a[x].r<=r)
    {
        (a[x].lazy+=c)%=mod;
        (a[x].sum+=len(x)*c)%=mod;

        return;
    }
    
    pushdown(x);
    
	int mid=a[x].l+a[x].r>>1;

    if(mid>=l)
        update(l,r,c,a[x].ls);
    
	if(mid<r)
        update(l,r,c,a[x].rs);
    
	pushup(x);
}

int query(int l,int r,int x)
{
    if(a[x].l>=l && a[x].r<=r)
        return a[x].sum;
    
	pushdown(x);
    
	int mid=a[x].l+a[x].r>>1,tot=0;

    if(mid>=l)
        tot+=query(l,r,a[x].ls);
    
	if(mid<r)
        tot+=query(l,r,a[x].rs);
    
	return tot%mod;
}

inline int sum(int x,int y)
{
    int ret=0;

    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]])
            swap(x,y);
        (ret+=query(id[top[x]],id[x],rt))%=mod;
        x=f[top[x]];
    }
    
	if(id[x]>id[y])
        swap(x,y);

    return (ret+query(id[x],id[y],rt))%mod;
}

inline void updates(int x,int y,int c)
{
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]])
            swap(x,y);
        update(id[top[x]],id[x],c,rt);
        x=f[top[x]];
    }
    
    if(id[x]>id[y])
        swap(x,y);
    
	update(id[x],id[y],c,rt);
}

signed main()
{
	ios::sync_with_stdio(0);

    cin >> n >> m >> r >> mod;

    for (long i=1; i<=n; i++)
        cin >> v[i];

    for (int x,y,i=1; i<n; i++)
    {
        cin >> x >> y;

        add(x,y);
        add(y,x);
    }

    cnt=0;
    dfs1(r);
    dfs2(r,r);

    cnt=0;
    build(1,n,rt=cnt++);

    for (int op,x,y,k,i=1; i<=m; i++)
    {
        cin >> op;

        if (op==1)
        {
            cin >> x >> y >> k;
        
            updates(x,y,k);
        }

        else if (op==2)
        {
            cin >> x >> y;

            cout << sum(x,y) << endl;
        }

        else if (op==3)
        {
            cin >> x >> y;

            update(id[x],id[x]+size[x]-1,y,rt);
        }

        else
        {
            cin >> x;

            cout << query(id[x],id[x]+size[x]-1,rt) << endl;
        }
    }

    return 0;
}
/*
██╗   ██╗ █████╗ ███╗   ██╗ ██████╗ ███████╗██████╗
╚██╗ ██╔╝██╔══██╗████╗  ██║██╔════╝ ╚══███╔╝██╔══██╗
 ╚████╔╝ ███████║██╔██╗ ██║██║  ███╗  ███╔╝ ██║  ██║
  ╚██╔╝  ██╔══██║██║╚██╗██║██║   ██║ ███╔╝  ██║  ██║
   ██║   ██║  ██║██║ ╚████║╚██████╔╝███████╗██████╔╝
   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═══╝ ╚═════╝ ╚══════╝╚═════╝
*/
2022/7/31 21:28
加载中...