正常的线段树板子awa
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define lid ( id << 1 )
#define rid ( id << 1 | 1 )
using namespace std;
long long num[114514],n,m;
long long a,b,c;
string ope;
struct sigment_tree {
long long l;
long long r;
long long sum;
long long lazy;
}tree[ 114514 * 4 ];
void build_tree( int id , int l , int r ) {
tree[id].l = l;
tree[id].r = r;
long long mid = ( l + r ) >> 1;
if ( l == r ) {
tree[id].sum = num[l];
return;
}
build_tree( lid , l , mid );
build_tree( rid , mid + 1 , r );
tree[id].sum = tree[lid].sum + tree[rid].sum;
return;
}
inline void pushdown( int id ) {
if ( tree[id].lazy ) {
//存在之前的标记
tree[lid].lazy += tree[id].lazy;
tree[rid].lazy += tree[id].lazy;
tree[lid].sum += tree[id].lazy * ( tree[lid].r - tree[lid].l + 1 );
tree[rid].sum += tree[id].lazy * ( tree[rid].r - tree[rid].l + 1 );
tree[id].lazy = 0;//别忘了清零捏~( ̄▽ ̄)~*
}
return;
}
void add_tree( int id , long long l , long long r , long long add_num ) {
if ( tree[id].l >= l && tree[id].r <= r ) {
//若在区间内,则直接加上add_num
tree[id].sum += add_num * ( tree[id].r - tree[id].l + 1 );
tree[id].lazy += add_num;
//这里是+= 不要写成等于,别问我怎么知道的呜呜呜 ┭┮﹏┭┮
return;
}
pushdown( id );//防止之前有lazy却没有随着这次传下去
long long mid = ( tree[id].l + tree[id].r ) >> 1;
if ( l <= mid ) add_tree( lid , l , r , add_num );
if ( r > mid ) add_tree( rid , l , r , add_num );//传lazy
//因为要更新的数是l到r的,所以范围要在l和r里面
tree[id].sum = tree[lid].sum + tree[rid].sum;
//随着lid与rid更新id的sum
return;
}
long long query_tree( int id , long long l , long long r ) {
if ( tree[id].l >= l && tree[id].r <= r) {
return tree[id].sum;
//若在区间内,因为在父亲节点已经更新了id的sum
//直接返回
}
pushdown( id );
//若l和r不在tree[id]的区间内,则下传lazy
long long ans = 0;
long long mid = ( tree[id].l + tree[id].r ) >> 1;
if ( l <= mid ) ans += query_tree( lid , l , r );
if ( mid < r ) ans += query_tree( rid , l , r );
return ans;
}
int main() {
scanf("%lld",&n);
for (int i = 1; i <= n; ++i) {
scanf("%lld",&num[i]);
}
if ( n != 0 ) build_tree( 1 , 1 , n );
scanf("%lld",&m);
for (int i = 1; i <= m; ++i) {
cin>>ope;
if ( ope == "ADD" ){
scanf("%lld%lld%lld",&a,&b,&c);
add_tree( 1 , a , b , c );
}
else {
scanf("%lld%lld",&a,&b);
printf( "%lld\n" , query_tree( 1 , a , b ) );
}
}
return 0;
}