//两个操作,第一个区间[a , b]内的所有数加c
//第二个询问区间[a , b]的值
//很标准的线段数
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1e5+10 ;
#define left v<<1
#define right v<<1|1
typedef __int64 ll ;
ll h[maxn] ;
struct node
{
int l , r ;
ll lazy ;
ll value;
}tree[maxn<<3] ;
void build(int l , int r , int v)
{
tree[v].l = l ;
tree[v].r = r ;
tree[v].lazy = 0 ;
if(l == r)
{
tree[v].value = h[l] ;
return ;
}
int mid = (l + r) >> 1 ;
build(l , mid , left) ;
build(mid+ 1 , r , right) ;
tree[v].value = tree[left].value + tree[right].value ;
}
void push_up(int v)
{
if(tree[v].lazy)
{
tree[left].lazy += tree[v].lazy ;
tree[right].lazy += tree[v].lazy ;
tree[left].value += (tree[left].r - tree[left].l + 1)*tree[v].lazy ;
tree[right].value += (tree[right].r - tree[right].l + 1)*tree[v].lazy ;
tree[v].lazy = 0 ;
}
}
void update(int a , int b , int v , ll num)
{
push_up(v) ;
if(tree[v].l == a && tree[v].r == b)
{
tree[v].lazy += num ;
tree[v].value += (tree[v].r - tree[v].l + 1)*tree[v].lazy ;
return ;
}
int mid = (tree[v].l + tree[v].r) >> 1 ;
if(a > mid)update(a , b , right , num) ;
else if(b <= mid)update(a , b , left , num) ;
else
{
update(a , mid , left , num) ;
update(mid + 1 , b , right ,num) ;
}
tree[v].value = tree[left].value + tree[right].value ;
}
ll query(int a , int b ,int v)
{
push_up(v) ;
if(tree[v].l == a && tree[v].r == b)
return tree[v].value ;
int mid = (tree[v].l + tree[v].r) >> 1 ;
if(a > mid)return query(a , b , right) ;
else if(b <= mid)return query(a , b , left) ;
else return query(a , mid , left) + query(mid+1 , b , right) ;
}
int main()
{
//freopen("in.txt" ,"r" , stdin) ;
int Q ,N ;
while(~scanf("%d%d" , &N ,&Q) )
{
for(int i = 1;i <= N;i++)
scanf("%I64d" ,&h[i]) ;
build(1 , N , 1) ;
char ch[10] ;
int a , b ; ll c ;
while(Q--)
{
scanf("%s" , ch) ;
if(ch[0] == ‘Q‘)
{
scanf("%d%d" ,&a , &b) ;
printf("%I64d\n" , query(a , b , 1)) ;
}
if(ch[0] == ‘C‘)
{
scanf("%d%d%I64d" , &a , &b , &c) ;
update(a , b ,1 , c) ;
}
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。