P3373【模板】线段树 2
1.将某区间每一个数乘上x
2.将某区间每一个数加上x
3.求出某区间每一个数的和
#include
using namespace std;
#define MAX 100005
#define ll long long
#define inf 0x3f3f3f
ll num[MAX];
int n,m;
ll p;
struct node{
ll val;
ll add;
ll mul;
int l,r;
}segtree[(MAX<<2)+5];
void build(int root,int nl,int nr){
segtree[root].add=0;
segtree[root].mul=1;
if(nl==nr){
segtree[root].val=num[nl];
return ;
}
int mid=nr+nl>>1;
build(root<<1,nl,mid);
build(root<<1|1,mid+1,nr);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;
segtree[root].val%=p;
}
void pushdown(int root,int nl,int nr){
int mid = nr+nl>>1;
segtree[root<<1].val=segtree[root<<1].val*segtree[root].mul+segtree[root].add*(mid-nl+1);
segtree[root<<1|1].val=segtree[root<<1|1].val*segtree[root].mul+segtree[root].add*(nr-mid);
segtree[root<<1].add=segtree[root<<1].add*segtree[root].mul+segtree[root].add;
segtree[root<<1|1].add=segtree[root<<1|1].add*segtree[root].mul+segtree[root].add;
segtree[root<<1].mul*=segtree[root].mul;
segtree[root<<1|1].mul*=segtree[root].mul;
segtree[root].add=0;
segtree[root].mul=1;
segtree[root<<1].val%=p;
segtree[root<<1|1].val%=p;
segtree[root<<1].add%=p;
segtree[root<<1|1].add%=p;
segtree[root<<1].mul%=p;
segtree[root<<1|1].mul%=p;
}
ll query(int root,int nl,int nr,int ql,int qr){
if(nl>qr||nr=ql&&nr<=qr){
return segtree[root].val;
}
pushdown(root,nl,nr);
int mid=nl+nr>>1;
return (query(root<<1,nl,mid,ql,qr)%p+query(root<<1|1,mid+1,nr,ql,qr)%p)%p;
}
void update(int root,int nl,int nr,int ql,int qr,int add){
if(nl>qr||nr=ql&&nr<=qr){
segtree[root].val+=(nr-nl+1)*add;
segtree[root].val%=p;
segtree[root].add+=add;
segtree[root].add%=p;
return ;
}
pushdown(root,nl,nr);
if(nl==nr){
segtree[root].val+=add;
segtree[root].val%=p;
return ;
}
int mid=nl+nr>>1;
update(root<<1,nl,mid,ql,qr,add);
update(root<<1|1,mid+1,nr,ql,qr,add);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;
segtree[root].val%=p;
}
void update2(int root,int nl,int nr,int ql,int qr,int mul){
if(nl>qr||nr=ql&&nr<=qr){
segtree[root].val*=mul;
segtree[root].add*=mul;
segtree[root].mul*=mul;
segtree[root].val%=p;
segtree[root].add%=p;
segtree[root].mul%=p;
return ;
}
pushdown(root,nl,nr);
if(nl==nr){
segtree[root].val*=mul;
segtree[root].val%=p;
return ;
}
int mid=nl+nr>>1;
update2(root<<1,nl,mid,ql,qr,mul);
update2(root<<1|1,mid+1,nr,ql,qr,mul);
segtree[root].val=segtree[root<<1].val+segtree[root<<1|1].val;
segtree[root].val%=p;
}
int main(){
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++){
scanf("%lld",&num[i]);
}
build(1,1,n);
for(int i=1;i<=m;i++){
int a;
scanf("%d",&a);
if(a==1){
int b,c,d;
scanf("%d%d%d",&b,&c,&d);
update2(1,1,n,b,c,d);
}
else if(a==2){
int b,c,d;
scanf("%d%d%d",&b,&c,&d);
update(1,1,n,b,c,d);
}
else if(a==3){
int b,c;
scanf("%d%d",&b,&c);
printf("%lld\n",query(1,1,n,b,c));
}
}
return 0;
}