# BZOJ1798: [Ahoi2009]Seq 维护序列seq 线段树

7 43
1 2 3 4 5 6 7
5
1 2 5 5
3 2 4
2 3 7 9
3 1 3
3 4 7

2
35
8

## HINT

【样例说明】

N= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000
M= 10 1000 1000 10000 60000 70000 80000 90000 100000 100000

## Solution

#include <bits/stdc++.h>

#define ll long long
#define inf 0x3f3f3f3f
#define il inline

namespace io {

#define out(a) write(a)
#define outn(a) out(a),putchar('\n')

#define I_int ll
inline I_int read() {
I_int x = 0 , f = 1 ; char c = getchar() ;
while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }
while( c >= '0' && c <= '9' ) { x = x * 10 + c - '0' ; c = getchar() ; }
return x * f ;
}
char F[ 200 ] ;
inline void write( I_int x ) {
if( x == 0 ) { putchar( '0' ) ; return ; }
I_int tmp = x > 0 ? x : -x ;
if( x < 0 ) putchar( '-' ) ;
int cnt = 0 ;
while( tmp > 0 ) {
F[ cnt ++ ] = tmp % 10 + '0' ;
tmp /= 10 ;
}
while( cnt > 0 ) putchar( F[ -- cnt ] ) ;
}
#undef I_int

}
using namespace io ;

using namespace std ;

#define N 100010
#define lc (rt<<1)
#define rc (rt<<1|1)

ll n , mod , a[ N ] , m ;
struct tree {
int l , r ;
ll mul , add , sum ;
} t[ N << 2 ] ;

void pushup( int rt ) { t[ rt ].sum = ( t[ lc ].sum + t[ rc ].sum ) % mod ; }

void pushdown( int ln , int rn , int rt ) {
ll &x1 = t[ rt ].add , &x2 = t[ rt ].mul ;
t[ lc ].sum = ( t[ lc ].sum * x2 + ln * x1 ) % mod ;
t[ rc ].sum = ( t[ rc ].sum * x2 + rn * x1 ) % mod ;
t[ lc ].mul = ( t[ lc ].mul * x2 ) % mod ;
t[ rc ].mul = ( t[ rc ].mul * x2 ) % mod ;
t[ lc ].add = ( t[ lc ].add * x2 + x1 ) % mod ;
t[ rc ].add = ( t[ rc ].add * x2 + x1 ) % mod ;
x1 = 0 ; x2 = 1 ;
}

void build( int l , int r , int rt ) {
t[ rt ].l = l ; t[ rt ].r = r ;  t[ rt ].mul = 1 ;
int mid = ( l + r ) >> 1 ;
if( l == r ) { t[ rt ].sum = a[ l ] ; return ; }
build( l , mid , lc ) ;
build( mid + 1 , r , rc ) ;
pushup( rt ) ;
}

void upd( int opt , int L , int R , int c , int rt ) {
//1 - add , 2 - mul
int l = t[ rt ].l , r = t[ rt ].r , mid = ( l + r ) >> 1 ;
if( L <= l && r <= R ) {
if( opt == 1 ) {
t[ rt ].sum = ( t[ rt ].sum + c * ( r - l + 1 ) ) % mod ;
t[ rt ].add = ( t[ rt ].add + c ) % mod ;
}
else {
t[ rt ].sum = ( t[ rt ].sum * c ) % mod ;
t[ rt ].add = ( t[ rt ].add * c ) % mod ;
t[ rt ].mul = ( t[ rt ].mul * c ) % mod ;
}
return ;
}
pushdown( mid - l + 1 , r - mid , rt ) ;
if( L <= mid ) upd( opt , L , R , c , lc ) ;
if( R > mid ) upd( opt , L , R , c , rc ) ;
pushup( rt ) ;
}

ll query( int L , int R , int rt ) {
int l = t[ rt ].l , r = t[ rt ].r , mid = ( l + r ) >> 1 ;
ll ans = 0 ;
if( L <= l && r <= R ) return t[ rt ].sum % mod ;
pushdown( mid - l + 1 , r - mid , rt ) ;
if( L <= mid ) ans = ( ans + query( L , R , lc ) ) % mod ;
if( R > mid ) ans = ( ans + query( L , R , rc ) ) % mod ;
return ans % mod ;
}

int main() {
n = read() , mod = read() ;
for( int i = 1 ; i <= n ; i ++ ) a[ i ] = read() % mod ;
build( 1 , n , 1 ) ; m = read() ;
for( int i = 1 ; i <= m ; i ++ ) {
ll opt = read() , t = read() , g = read() ;
if( opt == 1 ) {
ll c = read() % mod ;
upd( 2 , t , g , c , 1 ) ;
} else if( opt == 2 ) {
ll c = read() % mod ;
upd( 1 , t , g , c , 1 ) ;
} else outn( query( t , g , 1 ) ) ;
}
return 0 ;
}

posted @ 2018-11-11 02:18  henry_y  阅读(205)  评论(0编辑  收藏  举报