【模板】线段树 2

 【模板】线段树 2

乘法懒标等于0也要下传,每次乘法操作对加法也要进行

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+10;
int v[maxn*4],L[maxn*4],R[maxn*4],lazy1[maxn*4],lazy2[maxn*4];
int A[maxn];
int mod;
void build(int l,int r,int x)
{
    L[x]=l,R[x]=r;
    lazy1[x]=1,lazy2[x]=0;
    //v[x]=0;
    if(l==r)
    {
        v[x]=(A[l])%mod;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,x*2);
    build(mid+1,r,x*2+1);
    v[x]=(v[2*x]+v[2*x+1])%mod;
}
void pushdown(int x)
{
   // if(lazy1[x]): lazy1[x]==0
    {
        v[x*2]=(v[x*2]*lazy1[x])%mod;
        v[x*2+1]=(v[x*2+1]*lazy1[x])%mod;
        lazy1[x*2]=(lazy1[x]*lazy1[x*2])%mod;
        lazy1[x*2+1]=(lazy1[x]*lazy1[x*2+1])%mod;
        lazy2[x*2]=(lazy1[x]*lazy2[x*2])%mod;
        lazy2[x*2+1]=(lazy1[x]*lazy2[x*2+1])%mod;
        lazy1[x]=1;
     if(lazy2[x]){
        v[2*x]=(v[2*x]+lazy2[x]*(R[2*x]-L[2*x]+1)%mod)%mod;
        v[2*x+1]=(v[2*x+1]+lazy2[x]*(R[2*x+1]-L[2*x+1]+1)%mod)%mod;
        lazy2[x*2]=(lazy2[x]+lazy2[x*2])%mod;
        lazy2[x*2+1]=(lazy2[x]+lazy2[x*2+1])%mod;
        lazy2[x]=0;}

    }
}
void update1(int l,int r,int x,int t)
{
    if(l<=L[x]&&R[x]<=r)
    {
        v[x]=(v[x]+t*(R[x]-L[x]+1)%mod)%mod;
        lazy2[x]=(lazy2[x]+t)%mod;
        return ;
    }
    pushdown(x);
    int mid=(L[x]+R[x])/2;
    if(l<=mid)update1(l,r,x*2,t);
    if(r>mid)update1(l,r,x*2+1,t);
    v[x]=(v[2*x]+v[2*x+1])%mod;
}
void update2(int l,int r,int x,int t)
{
    if(l<=L[x]&&R[x]<=r)
    {
        v[x]=(v[x]*t)%mod;
        lazy2[x]=(lazy2[x]*t)%mod;
        lazy1[x]=(lazy1[x]*t)%mod;
        return ;
    }
    pushdown(x);
    int mid=(L[x]+R[x])/2;
    if(l<=mid)update2(l,r,x*2,t);
    if(r>mid)update2(l,r,x*2+1,t);
    v[x]=(v[2*x]+v[2*x+1])%mod;
}


int query(int l,int r,int x)
{

    if(l<=L[x]&&R[x]<=r)
    {
       // cout<<v[x]<<"QUE"<<endl;
        return v[x]%mod;
    }
    int mid=(L[x]+R[x])/2;
    int ans=0;
    pushdown(x);
    if(l<=mid)
        ans+=query(l,r,x*2)%mod;
    if(r>mid) ans=(ans+query(l,r,x*2+1))%mod;
    return ans%mod;
}
signed main()
{
    int n,m;
    int x,y,z,k;
    //while(
    //freopen("a.txt","w",stdout);
    scanf("%lld%lld%lld",&n,&m,&mod);
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%lld",&A[i]);
        }
        build(1,n,1);
        while(m--)
        {
           
            scanf("%lld",&x);
            if(x==2)
            {
                scanf("%lld%lld%lld",&y,&z,&k);
                update1(y,z,1,k);
            }
            else if(x==1)
            {
                scanf("%lld%lld%lld",&y,&z,&k);
                update2(y,z,1,k);
            }
            else
            {
                scanf("%lld%lld",&y,&z);

                cout<<query(y,z,1)<<'\n';
            }
        }
    }



}

 

posted @ 2019-08-30 08:31  liulex  阅读(234)  评论(0编辑  收藏  举报