线段树_乘法_加法

#include<iostream>

#define ll long long
const int N=100050;
using namespace std;
ll n,m,init[N],mod;
struct node{ll l,r,v,add,mul;}t[N<<2];


void update(int p)
{
    t[p].v=(t[p<<1].v+t[p<<1|1].v)%mod;
}

void build(int p,int l,int r)
{
    t[p].l=l; t[p].r=r; t[p].mul=1;
    if(l==r)
    {
        t[p].v=init[l];
        return ;        
    }
    int mid=(t[p].l+t[p].r)>>1;
    build(p<<1,l,mid); build(p<<1|1,mid+1,r);
    update(p);
}

ll getlen(int p)
{
    return t[p].r-t[p].l+1;
}
void pushdown(int p)
{
    ll add=t[p].add,mul=t[p].mul;
    t[p].mul=1; t[p].add=0;
    t[p<<1].v=(t[p<<1].v*mul+getlen(p<<1)*add)%mod;
    t[p<<1|1].v=(t[p<<1|1].v*mul+getlen(p<<1|1)*add)%mod;
    t[p<<1].add=(t[p<<1].add*mul+add)%mod;
    t[p<<1|1].add=(t[p<<1|1].add*mul+add)%mod;
    t[p<<1].mul=(t[p<<1].mul*mul)%mod;
    t[p<<1|1].mul=(t[p<<1|1].mul*mul)%mod;
}

void add(int p,int l,int r,ll k)
{
    if(l<=t[p].l&&r>=t[p].r)
    {
        t[p].v=(t[p].v+getlen(p)*k)%mod;
        t[p].add=(t[p].add+k)%mod;
        return ;
    }
    pushdown(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid) add(p<<1,l,r,k);
    if(r>mid) add(p<<1|1,l,r,k);
    update(p);
}

void mul(int p,int l,int r,ll k)
{
    if(l<=t[p].l&&r>=t[p].r)
    {
        t[p].v=(t[p].v*k)%mod;
        t[p].add=(t[p].add*k)%mod;
        t[p].mul=(t[p].mul*k)%mod;
        return ;
    }
    pushdown(p);
    int mid=(t[p].l+t[p].r)>>1;
    if(l<=mid) mul(p<<1,l,r,k);
    if(r>mid) mul(p<<1|1,l,r,k);
    update(p);
}

ll query(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r) return t[p].v;
    pushdown(p);
    ll mid=(t[p].l+t[p].r)>>1,re=0;
    if(l<=mid) re+=query(p<<1,l,r);
    if(r>mid) re+=query(p<<1|1,l,r);
    return re%mod;
}


int main()
{
    cin>>n>>m>>mod;
    for(int i=1;i<=n;i++) cin>>init[i];
    build(1,1,n);
    while(m--)
    {
        int opt,x,y,k; cin>>opt>>x>>y;
        if(opt==1) cin>>k,mul(1,x,y,k);
        if(opt==2) cin>>k,add(1,x,y,k);
        if(opt==3) cout<<query(1,x,y)<<endl;
    }

    return 0;
}
posted @ 2020-11-06 10:42  nenT  阅读(88)  评论(0)    收藏  举报