树剖30分求调
查看原帖
树剖30分求调
389476
lrt_2008楼主2022/6/8 22:44
#include<bits/stdc++.h>
#define gc getchar()
#define pc putchar
#define N 200100
#define Rg register
#define ll long long
#define lson(x) x<<1
#define rson(x) x<<1|1
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
using namespace std;
inline int lowbit(int x){return x&(-x);}
template<typename T>
inline void read(T &x)
{
    x=0;bool f=1;
    char c=gc;
    while(!isdigit(c)){if(c=='-')f=0;c=gc;}
    while(isdigit(c))
        x=(x<<1)+(x<<3)+(c-'0'),
        c=gc;
    x=f?x:-x;
    return ;
}
template<typename T>
void write(T x)
{
    if(x<0) pc('-'),x=-x;
    if(x>9) write(x/10);
    pc(x%10+'0');
    return ;
}
int n,m,root,MOD,a[N];
int dep[N],fa[N],siz[N],son[N],w[N],top[N],dfsx[N];
ll s[N<<2],lazy[N<<2],ans;
struct node
{
    int to,nxt;
}edge[N];int head[N],cnt,cntx;
inline void add(int u,int v)
{
    cnt++;
    edge[cnt].to=v;
    edge[cnt].nxt=head[u];
    head[u]=cnt;
    return ;
}
inline void pushdown(int u,int len)
{
    lazy[lson(u)]+=lazy[u];
    lazy[rson(u)]+=lazy[u];
    s[lson(u)]+=lazy[u]*(len-(len>>1));
    s[rson(u)]+=lazy[u]*(len>>1);
    s[lson(u)]%=MOD;s[rson(u)]%=MOD;
    lazy[u]=0;
    return ;
}
inline void query(int u,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {(ans+=s[u])%=MOD;return ;}
    else
    {
        int mid=l+r>>1;
        if(lazy[u]) pushdown(u,r-l+1);
        if(L<=mid) query(lson(u),l,mid,L,R);
        if(R>mid) query(rson(u),mid+1,r,L,R);
    }
    return ;
}
inline void update(int u,int l,int r,int L,int R,int k)
{
    if(L<=l&&r<=R)
        lazy[u]+=k,s[u]+=(r-l+1)*k;
    else
    {
        int mid=l+r>>1;
        if(lazy[u]) pushdown(u,r-l+1);
        if(L<=mid) update(lson(u),l,mid,L,R,k);
        if(R>mid) update(rson(u),mid+1,r,L,R,k);
        s[u]=(s[lson(u)]+s[rson(u)])%MOD;
    }
    return ;
}
inline void change1(int x,int y,int z)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        update(1,1,n,dfsx[top[x]],dfsx[x],z);
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    update(1,1,n,dfsx[x],dfsx[y],z);
    return ;
}
inline void change2(int x,int k)
{
    update(1,1,n,dfsx[x],dfsx[x]+siz[x]-1,k);
    return ;
}
inline int query1(int x,int y)
{
    int res=0;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        ans=0;
        query(1,1,n,dfsx[top[x]],dfsx[x]);
        (res+=ans)%=MOD;
        x=fa[top[x]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    ans=0;
    query(1,1,n,dep[x],dep[y]);
    (res+=ans)%=MOD;
    return res;
}
inline int query2(int x)
{
    ans=0;
    query(1,1,n,dfsx[x],dfsx[x]+siz[x]-1);
    return ans;
}
void dfs1(int u,int f,int d)
{
    dep[u]=d;fa[u]=f;siz[u]=1;
    int Max=-1;
    for(Rg int i=head[u];i;i=edge[i].nxt)
    {
        int to=edge[i].to;
        if(to==f) continue;
        dfs1(to,u,d+1);
        siz[u]+=siz[to];
        if(siz[to]>Max) son[u]=to,Max=siz[to];
    }
    return ;
}
void dfs2(int u,int t)
{
    cntx++;dfsx[u]=cntx;
    w[cntx]=a[u];top[u]=t;
    if(!son[u]) return ;
    dfs2(son[u],t);
    for(Rg int i=head[u];i;i=edge[i].nxt)
    {
        int to=edge[i].to;
        if(to==fa[u]||to==son[u]) continue;
        dfs2(to,to);
    }
    return ;
}
void build(int u,int l,int r)
{
    if(l==r){s[u]=w[l]%MOD;return ;}
    int mid=l+r>>1;
    build(lson(u),l,mid);
    build(rson(u),mid+1,r);
    s[u]=(s[lson(u)]+s[rson(u)])%MOD;
    return ;
}
int main()
{
    read(n);read(m);read(root);read(MOD);
    for(Rg int i=1;i<=n;i++) read(a[i]);
    for(Rg int i=1;i<n;i++)
    {
        int x,y;
        read(x);read(y);
        add(x,y);add(y,x);
    }
    dfs1(root,0,1);
    dfs2(root,root);
    build(1,1,n);
    while(m--)
    {
        int op,x,y,z;read(op);
        if(op==1)
        {
            read(x);read(y);read(z);
            z%=MOD;change1(x,y,z);
        }
        if(op==2)
        {
            read(x);read(y);
            write(query1(x,y));puts("");
        }
        if(op==3)
        {
            read(x);read(y);
            change2(x,y);
        }
        if(op==4)
        {
            read(x);
            write(query2(x));puts("");
        }
    }
    return 0;
}
2022/6/8 22:44
加载中...