POJ A Simple Problem with Integers 线段树的成段更新
A Simple Problem with Integers
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
Hint
/* 如果两个人的天堂 象是温馨的墙 囚禁你的梦想 幸福是否象是一扇铁窗 候鸟失去了南方*/
#include<cstdio>
#include<iostream>
#define M 100010
struct node{ int s , e ; long long add , sum ; }qe[M*4] ;//数据太大 需要 long long
using namespace std ;
long long Max , sum ;
void creat( int s , int e , int step ){ // 建树
qe[step].s = s ;
qe[step].e = e ;
qe[step].sum = 0 ;
qe[step].add = 0 ;
if( s == e ) return ;
int mid = ( s + e ) >> 1 ;
creat( s , mid , step << 1 ) ;
creat( mid + 1 ,e , step << 1 |1 ) ;
}
long long ma( long long a , long long b ){
if( a > b ) return a ;
return b ;
}
void pushdown(int step , int s , int e )
{
long long f = qe[step].add ;
if( f )
{ int mid = ( s + e ) >> 1 ;
qe[step<<1].add += f;
qe[step<<1|1].add += f ;
qe[step<<1].sum += f * ( qe[step<<1].e - qe[step<<1].s + 1 ) ;
qe[step<<1|1].sum += f * ( qe[step<<1|1].e - qe[step<<1|1].s + 1 ) ;
qe[step].add = 0 ; // 已经更新 子树 所以需要置为 0 避免下次重复更新子节点
}
}
void insert( long long i , long long mun , long long step ){ // 把线段树初始化
if( qe[step].s == qe[step].e ){
qe[step].sum = mun ;
return ;
}
int mid = ( qe[step].s + qe[step].e ) >> 1 ;
if( mid >= i )
insert( i , mun , step << 1 ) ;
else insert( i ,mun , step << 1 | 1 ) ;
qe[step].sum = qe[step<<1].sum + qe[step<<1|1].sum ;
return ;
}
void up( int s , int e , int add , int step ){
if( qe[step].s == s && qe[step].e == e ){
qe[step].add += add ;
qe[step].sum += ( add * ( e - s + 1 ) ) ;
return ;
}
pushdown( step ,s , e ) ; // 如果 当前的 线段 qe[].add 不为 0 就一起向下更新
int mid = ( qe[step].s + qe[step].e ) >> 1 ;
if( mid >= e ) up( s , e , add , step << 1 ) ;
else if( s > mid ) up( s , e , add , step << 1| 1 ) ;
else {
up( s , mid , add , step << 1 ) ;
up( mid + 1 , e , add , step <<1|1 ) ;
}
qe[step].sum = qe[step<<1].sum + qe[step<<1|1].sum ;//更新当前的 线段
return ;
}
long long find( int s , int e ,int step ){
if( s == qe[step].s && e == qe[step].e ){
return qe[step].sum ;
}
pushdown( step ,s , e ) ;// 查找的时候也要更新
int mid = ( qe[step]. s + qe[step].e ) >> 1 ;
if( mid >= e ) return find( s , e , step << 1 ) ;
else if( mid < s ) return find( s , e , step << 1 | 1 ) ;
else {
return find( s , mid , step << 1 ) + find( mid + 1 , e , step << 1 | 1 ) ;
}
}
int main()
{
int i , n , m , k , u , v ;
char o ;
//freopen( "in.txt" , "r" , stdin)
while( scanf( "%d%d" , &n , &m ) != EOF ){
creat( 1 , n , 1 ) ;
for( i = 1 ; i <= n ;i++ ) {
scanf( "%d" , &u ) ;
insert( i , u , 1 ) ;
}
while( m-- ){
scanf( " %c" , &o ) ;
if( o == 'C' ){
scanf( "%d%d%d" , &u , &v ,&k ) ;
up( u , v , k , 1 ) ;
}
else{
Max = 0 ; sum = 0 ;
scanf( "%d%d" , &u , &v ) ;
printf( "%lld\n" , find( u , v , 1 ) ) ;
}
}
}
}
代码:

浙公网安备 33010602011771号