线段树模版题
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000005;
ll n,m,mod,type,x,y,k;
ll ans[4*N],mul_tag[4*N],add_tag[4*N],aa[N];
inline ll ls(ll p)
{
return p<<1;
}
inline ll rs(ll p)
{
return p<<1|1;
}
inline void push_up(ll p)
{
ans[p]=(ans[ls(p)]+ans[rs(p)])%mod;
}
inline void push_down(ll p,ll l,ll r)
{
ll m=(l+r)>>1;
ans[ls(p)]=((ans[ls(p)]*mul_tag[p]%mod)+(add_tag[p]*(m-l+1))%mod)%mod;
ans[rs(p)]=((ans[rs(p)]*mul_tag[p]%mod)+(add_tag[p]*(r-m))%mod)%mod;
mul_tag[ls(p)]=(mul_tag[ls(p)]*mul_tag[p])%mod;
mul_tag[rs(p)]=(mul_tag[rs(p)]*mul_tag[p])%mod;
add_tag[ls(p)]=((add_tag[ls(p)]*mul_tag[p])%mod+add_tag[p])%mod;
add_tag[rs(p)]=((add_tag[rs(p)]*mul_tag[p])%mod+add_tag[p])%mod;
mul_tag[p]=1;
add_tag[p]=0;
}
inline void build(ll p,ll l,ll r)
{
mul_tag[p]=1,add_tag[p]=0;
if(l==r)
{
ans[p]=aa[l];
return ;
}
ll m=(l+r)>>1;
build(ls(p),l,m);
build(rs(p),m+1,r);
push_up(p);
}
inline void update_add(ll ql,ll qr,ll l,ll r,ll p, ll k)
{
if(ql<=l&&r<=qr)
{
ans[p]=(ans[p]+(r-l+1)*k)%mod;
add_tag[p]=(add_tag[p]+k)%mod;
return ;
}
push_down(p,l,r);
ll m=(l+r)>>1;
if(m>=ql) update_add(ql,qr,l,m,ls(p),k);
if(m<qr) update_add(ql,qr,m+1,r,rs(p),k);
push_up(p);
}
inline void update_mul(ll ql,ll qr,ll l,ll r,ll p,ll k)
{
if(ql<=l&&r<=qr)
{
ans[p]=(ans[p]*k)%mod;
mul_tag[p]=(mul_tag[p]*k)%mod;
add_tag[p]=(add_tag[p]*k)%mod;
return ;
}
push_down(p,l,r);
ll m=(l+r)>>1;
if(m>=ql) update_mul(ql,qr,l,m,ls(p),k);
if(m<qr) update_mul(ql,qr,m+1,r,rs(p),k);
push_up(p);
}
ll query(ll ql,ll qr, ll l,ll r, ll p)
{
ll res=0;
if(ql<=l&&r<=qr)
{
return ans[p];
}
push_down(p,l,r);
ll m=(l+r)>>1;
if(m>=ql) res=(res+query(ql,qr,l,m,ls(p)))%mod;
if(m<qr) res=(res+query(ql,qr,m+1,r,rs(p)))%mod;
return res;
}
int main ()
{
scanf("%lld%lld%lld",&n,&m,&mod);
for(int i=1;i<=n;++i)
{
scanf("%lld",&aa[i]);
}
build(1,1,n);
for(int i=1;i<=m;++i)
{
scanf("%lld%lld%lld",&type,&x,&y);
if(type!=3)
{
scanf("%lld",&k);
}
if(type==1)
{
update_mul(x,y,1,n,1,k);
}
if(type==2)
{
update_add(x,y,1,n,1,k);
}
if(type==3)
{
printf("%lld\n",query(x,y,1,n,1));
}
}
return 0;
}