# BZOJ 1798: [Ahoi2009]Seq 维护序列seq( 线段树 )

---------------------------------------------------------------

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<vector>

#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
#define L( x ) ( x << 1 )
#define R( x ) ( L( x ) ^ 1 )
#define mid( l , r ) ( ( l + r ) >> 1 )
#define LC( x ) tree[ L( x ) ]
#define RC( x ) tree[ R( x ) ]

using namespace std;

const int maxn = 100000 + 5;

int mod;

struct Node {
int l , r , mul , add , sum;
Node() : mul( 1 ) , add( 0 ) {}
};

Node tree[ maxn << 2 ];

void pushdown( int x ) {
Node &o = tree[ x ];
if( o.mul >= 0 ) {
LC( x ).mul = 1LL * o.mul * LC( x ).mul % mod;
RC( x ).mul = 1LL * o.mul * RC( x ).mul % mod;
LC( x ).add = 1LL * LC( x ).add * o.mul % mod;
RC( x ).add = 1LL * RC( x ).add * o.mul % mod;
o.mul = 1;
}
}
}

void maintain( int x ) {
Node &o = tree[ x ];
if( o.r > o.l )
o.sum = LC( x ).sum + RC( x ).sum;
o.sum = ( 1LL * o.sum * o.mul + 1LL * o.add * ( o.r - o.l + 1 ) ) % mod;
if( o.l == o.r )
o.mul = 1 , o.add = 0;
}

int L , R , v , op;

void update( int x ) {
Node &o = tree[ x ];
if( L <= o.l && o.r <= R ) {
if( op == 1 ) {
o.mul = 1LL * o.mul * v % mod;
} else
} else {
pushdown( x );
int m = mid( o.l , o.r );
if( L <= m ) update( L( x ) ); else maintain( L( x ) );
if( m < R ) update( R( x ) ); else maintain( R( x ) );
}
maintain( x );
}

int query( int x ) {
Node &o = tree[ x ];
if( L <= o.l && o.r <= R )
return o.sum;
int m = mid( o.l , o.r );
int ans = 0;
pushdown( x );
maintain( L( x ) );
maintain( R( x ) );
if( L <= m ) ans = query( L( x ) );
if( m < R ) ans += query( R( x ) );
return ans % mod;
}

int seq[ maxn ];

void build( int x , int l , int r ) {
Node &o = tree[ x ];
o.l = l , o.r = r;
if( l == r ) {
o.sum = seq[ l ];
return;
}
int m = mid( l , r );
build( L( x ) , l , m );
build( R( x ) , m + 1 , r );
maintain( x );
}

int main() {
freopen( "test.in" , "r" , stdin );
int n;
cin >> n >> mod;
Rep( i , n )
scanf( "%d" , seq + i );

build( 1 , 1 , n );
int m;
cin >> m;
while( m-- ) {
scanf( "%d%d%d" , &op , &L , &R );
if( op == 3 ) printf( "%d\n" , query( 1 ) );
else {
scanf( "%d" , &v );
update( 1 );
}
}
return 0;
}

---------------------------------------------------------------

## 1798: [Ahoi2009]Seq 维护序列seq

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 3347  Solved: 1240
[Submit][Status][Discuss]

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

## Source

posted @ 2015-06-11 12:30  JSZX11556  阅读(209)  评论(0编辑  收藏  举报