以下代码:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cmath>
#define int unsigned long long
#define lson (pos << 1)
#define rson (pos << 1 | 1)
using namespace std ;
//乘法tag一定要赋初始值!!!!
//乘法tag一定要赋初始值!!!!
//乘法tag一定要赋初始值!!!!
//乘法tag一定要赋初始值!!!!
struct SegTree {
int tag ;
int mul=1 ;
int sum ;
};
SegTree tre[500005] ;
//mul乘 plu加
//更新
void pushup(int pos){
tre[pos].sum = tre[lson].sum + tre[rson].sum ;
return ;
}
int a[500005] , mod , n , q , m ;
//建树
void build(int pos , int l , int r ){
if( l == r ){
tre[pos].sum = a[l] ;
return ;
}
int mid ;
mid = (l + r ) >> 1 ;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(pos);
return ;
}
//下传懒标记
void pushdown(int pos , int l , int r ){
//先乘后加
if( tre[pos].tag != 0 || tre[pos].mul != 1 ){
int mid ;
mid=(l+r) >> 1 ;
tre[lson].tag = ( tre[lson].tag * tre[pos].mul + tre[pos].tag) % mod ;
tre[lson].sum = ( tre[lson].sum * tre[pos].mul + tre[pos].tag*(mid+1-l)) % mod ;
tre[lson].mul = tre[lson].mul * tre[pos].mul % mod ;
tre[rson].tag = ( tre[rson].tag * tre[pos].mul + tre[pos].tag) % mod ;
tre[rson].sum = ( tre[rson].sum * tre[pos].mul + tre[pos].tag*(r-mid)) % mod;
tre[rson].mul = tre[rson].mul * tre[pos].mul % mod ;
}
tre[pos].tag = 0 ;
tre[pos].mul = 1 ;
return ;
}
void update_mul(int pos , int l , int r , int ql , int qr , int k){
if( ql <= l && qr >= r ){
tre[pos].mul = tre[pos].mul * k % mod ;
tre[pos].sum = tre[pos].sum * k % mod ;
tre[pos].tag = tre[pos].tag * k % mod ;
return ;
}
pushdown(pos , l , r );
int mid ;
mid = ( l + r ) >> 1 ;
if( ql <= mid ){
update_mul(lson , l , mid , ql , qr , k );
}
if( qr > mid ){
update_mul(rson , mid+1 , r , ql , qr , k );
}
pushup(pos);
return ;
}
void update_plus( int pos , int l , int r , int ql , int qr , int k ){
pushdown( pos , l , r );
if( ql <= l && qr >= r ){
tre[pos].sum = tre[pos].sum % mod + (k * ( r - l + 1)) % mod ;
tre[pos].tag = tre[pos].tag % mod + k % mod ;
return ;
}
int mid = ( l + r ) >> 1 ;
if( ql <= mid ){
update_plus(lson , l , mid , ql , qr , k );
}
if( qr > mid ){
update_plus(rson , mid+1 , r , ql , qr , k );
}
pushup( pos );
return ;
}
int query( int pos , int l , int r , int ql , int qr ){
if( ql <= l && qr >= r ){
return tre[pos].sum % mod ;
}
pushdown( pos , l , r );
int mid ;
mid = ( l + r ) >> 1 ;
int res = 0 ;
if( ql <= mid ){
res = ( res + query( lson , l , mid , ql , qr )) % mod ;
}
if( qr > mid ){
res = ( res + query( rson , mid+1 , r , ql , qr )) % mod ;
}
return res % mod ;
}
signed main(){
scanf("%lld%lld%lld" , &n , &q , &m );
for( int i = 1 ; i <= n ; i ++ ){
scanf("%lld" , &a[i] );
}
mod = m ;
build(1 , 1 , n );
int x , y , k , kind ;
k = x = y = kind = 0 ;
while( q -- ){
scanf("%lld" , &kind );
if( kind == 1 ){
scanf("%lld%lld%lld" , &x , &y , &k );
update_mul( 1 , 1 , n , x , y , k );
}
if( kind == 2 ){
scanf("%lld%lld%lld" , &x , &y , &k );
update_plus( 1 , 1 , n , x , y , k );
}
if( kind == 3 ){
scanf("%lld%lld" , &x , &y );
int ans = 0 ;
ans = query(1 , 1 , n , x , y );
printf("%lld\n" , ans );
}
}
return 0 ;
}
感谢大佬!好人一生平安!!!