P3373 segment tree 2

 

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll N=100001;
ll sum[N<<2],lazy1[N<<2],lazy2[N<<2];
ll a[N];
ll n,m,p;

inline ll read()
{
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

void build(ll cnt,ll l,ll r)
{
    if(l==r) 
    {
        sum[cnt]=a[l]%p;
        return;
    }
    else 
    {
        ll mid=(l+r)>>1;
        build(cnt<<1,l,mid);
        build((cnt<<1)|1,mid+1,r);
        sum[cnt]=(sum[cnt<<1]+sum[(cnt<<1)|1])%p;
    }
}

inline bool cover(ll nl,ll nr,ll l,ll r)
{
    return l<=nl&&r>=nr;
}

inline bool intersection(ll nl,ll nr,ll l,ll r)
{
    return l<=nr&&r>=nl;
}

void pushdown(ll cnt,ll l,ll r)
{
    ll mid=(l+r)>>1;
    lazy1[cnt<<1]=(lazy1[cnt<<1]*lazy2[cnt]+lazy1[cnt])%p;
    lazy1[(cnt<<1)|1]=(lazy1[(cnt<<1)|1]*lazy2[cnt]+lazy1[cnt])%p;
    lazy2[cnt<<1]=(lazy2[cnt<<1]*lazy2[cnt]%p)%p;
    lazy2[(cnt<<1)|1]=(lazy2[(cnt<<1)|1]*lazy2[cnt]%p)%p;
    sum[cnt<<1]=((lazy1[cnt]*(mid-l+1)%p)+(sum[cnt<<1]*lazy2[cnt]%p))%p;
    sum[cnt<<1|1]=((lazy1[cnt]*(r-mid)%p)+(sum[cnt<<1|1]*lazy2[cnt]%p))%p;
    lazy2[cnt]=1;
    lazy1[cnt]=0;
}

void add1(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
{
    if(cover(nl,nr,l,r))
    {
        sum[cnt]=(sum[cnt]+(nr-nl+1)*a%p)%p;
        lazy1[cnt]=(lazy1[cnt]+a%p)%p;
        return ;
    }
    pushdown(cnt,nl,nr);
    ll mid=(nl+nr)>>1;
    if(intersection(nl,mid,l,r)) add1(cnt<<1,nl,mid,l,r,a);
    if(intersection(mid+1,nr,l,r)) add1(cnt<<1|1,mid+1,nr,l,r,a);
    sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
}

void add2(ll cnt,ll nl,ll nr,ll l,ll r,ll a)
{
    if(cover(nl,nr,l,r))
    {
        sum[cnt]=(sum[cnt]*a)%p;
        lazy1[cnt]=(lazy1[cnt]*a)%p;
        lazy2[cnt]=(lazy2[cnt]*a)%p;
        return ;
    }
    pushdown(cnt,nl,nr);
    ll mid=(nl+nr)>>1;
    if(intersection(nl,mid,l,r)) add2(cnt<<1,nl,mid,l,r,a);
    if(intersection(mid+1,nr,l,r)) add2(cnt<<1|1,mid+1,nr,l,r,a);
    sum[cnt]=(sum[cnt<<1]+sum[cnt<<1|1])%p;
}

ll query(ll cnt,ll nl,ll nr,ll l,ll r)
{
    if(cover(nl,nr,l,r))
    {
        return sum[cnt]%p;
    }
    pushdown(cnt,nl,nr);
    ll mid=(nl+nr)>>1;
    ll ans=0;
    if(intersection(nl,mid,l,r)) ans+=query(cnt<<1,nl,mid,l,r)%p;
    if(intersection(mid+1,nr,l,r)) ans+=query(cnt<<1|1,mid+1,nr,l,r)%p;
    return ans;
}


int main()
{
    n=read(),m=read(),p=read();
    for(ll i=1;i<=n;i++)
        a[i]=read();
    for(int i=1;i<=N<<2;i++) lazy2[i]=1;
    build(1,1,n);
    while(m--)
    {
        ll k;
        k=read();
        if(k==1)
        {
            ll l=read(),r=read(),t=read();
            add2(1,1,n,l,r,t);
        }
        if(k==2)
        {
            ll l=read(),r=read(),t=read();
            add1(1,1,n,l,r,t);
        }
        if(k==3)
        {
            ll l=read(),r=read();
            printf("%lld\n",query(1,1,n,l,r)%p);
        }
    }
}

 

Guess you like

Origin www.cnblogs.com/lcezych/p/11116318.html