AcWing 1277. 维护序列

 

 

#include <bits/stdc++.h>
#define ll long long
#define N 4000010
using namespace std;
ll t[N],a[N],num[N],mt[N],mod;
void build(ll p, ll l, ll r)
{
    mt[p]=1;
    if(l==r){num[p]=a[l]%mod;return;}
    ll mid=(l+r)>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    num[p]=(num[p<<1]+num[p<<1|1])%mod;
}
void mp(ll p,ll l,ll r,ll x){mt[p]=mt[p]*x%mod;t[p]=t[p]*x%mod;num[p]=num[p]*x%mod;}
void upd(ll p,ll l,ll r,ll x){t[p]=(t[p]+x)%mod;num[p]=(num[p]+(r-l+1)*x)%mod;}
void pd(ll p,ll l,ll r)
{
    ll mid =(l+r)>>1;
    mp(p<<1,l,mid,mt[p]);mp(p<<1|1,mid+1,r,mt[p]);
    upd(p<<1,l,mid,t[p]);upd(p<<1|1,mid+1,r,t[p]);
    mt[p]=1;t[p]=0;
}
void add(ll L,ll R,ll l,ll r,ll p,ll x)
{
    if (L<=l&&r<=R){t[p]=(t[p]+x)%mod;num[p]=(num[p]+(r-l+1)*x)%mod;return;}
    pd(p,l,r);
    ll mid=(l+r)>>1;
    if (L<=mid)add(L,R,l,mid,p<<1,x);
    if (R>=mid+1) add(L,R,mid+1,r,p<<1|1,x);
    num[p]=(num[p<<1]+num[p<<1|1])%mod;
}
void mc(ll L, ll R, ll l, ll r, ll p, ll x)
{
    if (L<=l&&r<=R){t[p]=t[p]*x%mod;mt[p]=mt[p]*x%mod;num[p]=num[p]*x%mod;return;}
    pd(p,l,r);
    ll mid=(l+r)>>1;
    if(L<=mid)mc(L,R,l,mid,p<<1,x);
    if(R>=mid+1)mc(L,R,mid+1,r,p<<1|1,x);
    num[p]=(num[p<<1]+num[p<<1|1])%mod;
}
ll Q(ll L,ll R, ll l, ll r, ll p)
{
    if (L<=l&&r<=R){return num[p]%mod;}
    pd(p,l,r);
    ll ans=0,mid=(l+r)>>1;
    if(L<=mid)ans+=Q(L,R,l,mid,p<<1);
    if(R>=mid+1)ans+=Q(L,R,mid+1,r,p<<1|1);
    return ans%mod;
}
int main()
{
    ll n, m;
    cin>>n>>mod;
    for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
    cin>>m;
    build(1,1,n);
    for (ll i=1,type,l,r,x;i<=m;i++)
    {
        scanf("%lld", &type);
        if(type==1){scanf("%lld%lld%lld", &l,&r,&x); mc(l, r,1,n,1,x);}
        else if(type==2){scanf("%lld%lld%lld",&l,&r,&x);add(l,r,1,n,1,x);}
        else{scanf("%lld%lld", &l, &r);printf("%lld\n",Q(l,r,1,n,1)%mod);}
    }
    return 0;
}

 

posted @ 2021-02-03 11:11  君与  阅读(75)  评论(0编辑  收藏  举报