树上求和

树上求和 https://ac.nowcoder.com/acm/problem/19428
    
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const int MOD=23333;
#define ll long long
struct sgt_tree
{
    #define ls (x<<1)
    #define rs (x<<1|1)
    ll lz[maxn*20],s1[maxn*20],s2[maxn*20];
    ll val[maxn];
    ll mul(ll a,ll b)
    {
        return ((a%MOD)*(b%MOD))%MOD;
    }
    ll mul(ll a,ll b,ll c)
    {
        return mul(a,b)*c%MOD;
    }
    void pushup(int x)
    {
        s1[x]=(s1[ls]+s1[rs])%MOD;
        s2[x]=(s2[ls]+s2[rs])%MOD;
    }
    void build(int x,int l,int r)
    {


        if(l==r)
        {
            s1[x]=val[l]%MOD;
            s2[x]=(s1[x]*s1[x])%MOD;
            return;
        }
        int mid=(l+r)>>1;
        build(ls,l,mid);
        build(rs,mid+1,r);
        pushup(x);
    }
    void pushdown(int x,int l,int r)
    {
        if(!lz[x])return;
        int mid=(l+r)>>1;
        lz[ls]=(lz[ls]+lz[x])%MOD;
        lz[rs]=(lz[rs]+lz[x])%MOD;
        s2[ls]=s2[ls]+mul(mid-l+1,lz[x],lz[x])+mul(s1[ls],2*lz[x])%MOD;
        s2[rs]=s2[rs]+mul(r-mid,lz[x],lz[x])+mul(s1[rs],2*lz[x])%MOD;
        s1[ls]=(s1[ls]+mul(mid-l+1,lz[x]))%MOD;
        s1[rs]=(s1[rs]+mul(r-mid,lz[x]))%MOD;
        lz[x]=0;
    }
    ll query(int x,int l,int r,int ql,int qr)
    {
        if(l>qr||r<ql)return (ll)0;
        if(ql<=l&&r<=qr)return s2[x]%MOD;
        pushdown(x,l,r);
        int mid=(l+r)>>1;
        ll res=0;
        if(ql<=mid)res+=query(ls,l,mid,ql,qr);
        if(mid<qr)res+=query(rs,mid+1,r,ql,qr);
        return res%MOD;
    }
    void update(int x,int l,int r,int ql,int qr,ll v)
    {
        if(l>qr||r<ql)return;
        if(ql<=l&&r<=qr)
        {
            lz[x]=(lz[x]+v)%MOD;
            s2[x]=(s2[x]+mul(v,v,r-l+1)+mul(s1[x],2*v))%MOD;
            s1[x]=(s1[x]+mul(v,r-l+1))%MOD;
            return ;
        }
        pushdown(x,l,r);
        int mid=(l+r)>>1;
        update(ls,l,mid,ql,qr,v);
        update(rs,mid+1,r,ql,qr,v);
        pushup(x);
    }
    void debug(int x,int l,int r)
    {
        cout<<"x="<<x<<" l="<<l<<" r="<<r<<" s1[x]="<<s1[x]<<" s2[x]="<<s2[x]<<endl;
        if(l==r)return;
        int mid=(l+r)>>1;
        pushdown(x,l,r);
        debug(ls,l,mid);
        debug(rs,mid+1,r);
    }
    void debug(int l,int r)
    {
        debug(1,l,r);
        system("pause");
    }
    #undef ls
    #undef rs
}sgt;
vector<int> go[maxn];
int n,m;
int in[maxn],out[maxn],a[maxn],tot;
void dfs(int u,int fa)
{
    in[u]=++tot;
    sgt.val[tot]=a[u];
    for(auto v:go[u]){
        if(v==fa)continue;
        dfs(v,u);
    }
    out[u]=tot;
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<n;i++)
    {
        int a,b;
        cin>>a>>b;
        go[a].push_back(b);
        go[b].push_back(a);
    }

    dfs(1,0);

    sgt.build(1,1,n);
    //debug();

    while(m--)
    {
        int op,x,y;
        cin>>op;
        if(op==1)
        {
            cin>>x>>y;
            sgt.update(1,1,n,in[x],out[x],y);
        }else
        {
            cin>>x;
            cout<<sgt.query(1,1,n,in[x],out[x])%MOD<<endl;
        }

    }
    return 0;
}

posted @ 2021-10-06 00:00  warmhearthhh  阅读(44)  评论(0)    收藏  举报