// 30 pts
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5*4+5;
int n,q,m;
int a[N],tree[N],mark1[N],mark2[N];
void build(int l=1,int r=n,int p=1){
if(l==r) tree[p]=a[l];
else{
int mid=l+r>>1;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
tree[p]=tree[p*2]+tree[p*2+1];
}
return ;
}
void doit(){
for(int i=1;i<=n;++i){
cin>>a[i];
}
fill(mark1,mark1+n*4,1);
build();
return;
}
void push_down(int p,int l,int r){
int mid=l+r>>1;
tree[p*2]=tree[p*2]*mark1[p]+mark2[p]*(mid-l+1);
tree[p*2+1]=tree[p*2+1]*mark1[p]+mark2[p]*(r-mid);
mark1[p*2]*=mark1[p];
mark1[p*2+1]*=mark1[p];
mark2[p*2]=mark2[p*2]*mark1[p]+mark2[p];
mark2[p*2+1]=mark2[p*2+1]*mark1[p]+mark2[p];
mark1[p]=1;
mark2[p]=0;
}
void C_f(int l,int r,int d,int p=1,int cl=1,int cr=n){
if(r<cl||l>cr) return;
else if(l<=cl&&r>=cr){
tree[p]=tree[p]*d;
mark1[p]=mark1[p]*d;
mark2[p]=mark2[p]*d;
}
else{
int mid=cl+cr>>1;
push_down(p,cl,cr);
C_f(l,r,d,p*2,cl,mid);
C_f(l,r,d,p*2+1,mid+1,cr);
tree[p]=tree[p*2]+tree[p*2+1];
}
return ;
}
void J_f(int l,int r,int d,int p=1,int cl=1,int cr=n){
if(r<cl||l>cr) return;
else if(l<=cl&&r>=cr){
tree[p]=tree[p]+d*(cr-cl+1);
mark2[p]=mark2[p]+d;
}
else{
int mid=cl+cr>>1;
push_down(p,cl,cr);
J_f(l,r,d,p*2,cl,mid);
J_f(l,r,d,p*2+1,mid+1,cr);
tree[p]=tree[p*2]+tree[p*2+1];
}
return;
}
int query(int l,int r,int p=1,int cl=1,int cr=n){
if(r<cl||l>cr) return 0;
else if(l<=cl&&r>=cr){
return tree[p];
}
else{
int mid=cl+cr>>1;
push_down(p,cl,cr);
return query(l,r,p*2,cl,mid)+query(l,r,p*2+1,mid+1,cr);
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>q>>m;
doit();
while(q--){
int flag,x,y,k;
cin>>flag;
if(flag==1){
cin>>x>>y>>k;
C_f(x,y,k);
}
else if(flag==2){
cin>>x>>y>>k;
J_f(x,y,k);
}
else if(flag==3){
cin>>x>>y;
cout<<query(x,y)%m<<"\n";
}
}
return 0;
}
修改后
#include <iostream>
#include <vector>
#define int long long
#define over(i,a,b) for(int i = (int)a ; i <= (int)b ; i ++ )
using namespace std ;
const int N = 100010 ;
int a[N] , n , m , mod ;
struct info{
int l , r , val , add , mul ;
}seg[N *4] ;
void updata(int id ){
seg[id].val = seg[id * 2].val + seg[id * 2 + 1].val ;
seg[id].val %= mod ;
}
void build(int id ,int l , int r){
seg[id].l = l , seg[id].r = r , seg[id].mul = 1 ,seg[id].add = 0;
if(l == r){
seg[id].val = a[l] % mod ;
}else{
int mid = (l + r) / 2 ;
build(id * 2 , l , mid );
build(id * 2 + 1, mid + 1 , r ) ;
updata(id) ;
}
}
void settag(int id , int x , int y){
seg[id].val = x * seg[id].val % mod + y * (seg[id].r - seg[id].l + 1) % mod ;
if(x != 1) seg[id].add *= x , seg[id].mul *= x ;
if(y != 0) seg[id].add += y ;
seg[id].add %= mod ;
seg[id].mul %= mod ;
}
void pushtag(int id){
settag(id * 2 , seg[id].mul , seg[id].add) ;
settag(id * 2 + 1 , seg[id].mul , seg[id].add ) ;
seg[id].add = 0 , seg[id].mul = 1 ;
}
void modify(int id , int l , int r , int ql , int qr , int val1 , int val2 ){
if(l >= ql && qr >= r){
settag(id,val1,val2) ;
}else{
pushtag(id) ;
int mid = ( l + r ) / 2 ;
if(ql <= mid )modify(id * 2 , l , mid , ql , qr , val1 , val2 ) ;
if(qr > mid )modify(id * 2 + 1 , mid + 1 , r , ql , qr , val1 , val2 ) ;
updata(id) ;
}
}
int query(int id , int l , int r , int ql , int qr ){
if(l >= ql && qr >= r){
return seg[id].val ;
}else{
pushtag(id);
int mid = (l + r) / 2 ;
int res = 0 ;
if(ql <= mid ) res += query( id * 2 , l , mid , ql , qr ) % mod ;
if(qr > mid ) res += query(id * 2 + 1 , mid + 1 , r , ql , qr ) % mod ;
return res ;
}
}
signed main(){
cin >> n >> m >> mod ;
over(i,1,n) cin >> a[i] ;
build(1,1,n) ;
//over(i,1,10) cout << seg[i].val << " " ;
over(i,1,m){
int ty ; cin >> ty ;
int x , y , k ;
if(ty == 1){
cin >> x >> y >> k ;
modify(1,1,n,x,y,k,0) ;
}else if(ty == 2){
cin >> x >> y >> k ;
modify(1,1,n,x,y,1,k) ;
}else{
cin >> x >> y ;
//over(i,1,10) cout << seg[i].val << " " ;
cout << query(1,1,n,x,y) % mod << "\n" ;
}
}
return 0 ;
}