裸的线段树
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long sum[410000];
long long add[410000];
long long N, Q;
long long lc( long long root ){
return 2 * root;
}
long long rc( long long root ){
return 2 * root + 1;
}
void PushUp( long long root ){
sum[root] = sum[lc(root)] + sum[rc(root)];
}
void built( long long l, long long r, long long root ){
if( l == r ){
scanf( "%lld", &sum[root] );
add[root] = 0;
return;
}
long long mid = ( l + r ) / 2;
built( l, mid, lc( root ) );
built( mid + 1, r, rc( root ) );
add[root] = 0;
PushUp( root );
}
void PushDown( long long root, long long l, long long r ){
if( add[root] ){
add[lc(root)] += add[root];
add[rc(root)] += add[root];
sum[lc(root)] += add[root] * ( ( l + r ) / 2 - l + 1 );
sum[rc(root)] += add[root] * ( r - ( l + r ) / 2 );
add[root] = 0;
}
}
long long query( long long L, long long R, long long l, long long r, long long root ){
if( L <= l && R >= r ){
return sum[root];
}
PushDown( root, l, r );
long long ans = 0, mid = ( l + r ) / 2;
if( L <= mid ) ans += query( L, R, l, mid, lc( root ) );
if( R > mid ) ans += query( L, R, mid + 1, r, rc( root ) );
PushUp( root );
return ans;
}
void Add( long long num, long long L, long long R, long long l, long long r, long long root ){
if( L <= l && R >= r ){
add[root] += num;
sum[root] += num * ( r - l + 1 );
return;
}
PushDown( root, l, r );
long long mid = ( l + r ) / 2;
if( L <= mid ) Add( num, L, R, l, mid, lc( root ) );
if( R > mid ) Add( num, L, R, mid + 1, r, rc( root ) );
PushUp( root );
}
int main(){
while( scanf( "%lld%lld", &N, &Q ) != EOF ){
built( 1, N, 1 );
for( long long i = 0; i < Q; i++ ){
char s[10];
long long temp1, temp2, temp3;
scanf( "%s%lld%lld", s, &temp1, &temp2 );
if( s[0] == 'Q' ){
cout << query( temp1, temp2, 1, N, 1 ) << endl;
}else{
scanf( "%lld", &temp3 );
Add( temp3, temp1, temp2, 1, N, 1 );
}
}
}
return 0;
}