#include <iostream>
using namespace std;
#define MAX_N 100005
#define MAX_Q 100005
typedef long long ll;
const int DAT_SIZE = (1<<18) - 1;
//输入
static int N,Q;
static int A[MAX_N];
//char T[MAX_Q];
//static int L[MAX_Q],R[MAX_Q],X[MAX_Q];
//线段树
ll data[DAT_SIZE],datb[DAT_SIZE];
//对区间[a,b)同时加上x
//k是结点编号对应区间[l,r)
void add(int a,int b,int x,int k,int l,int r){
if (a<=l&&r<=b)
data[k]+=x;
else if (l<b&&a<r)
{
datb[k] +=(min(b,r) - max(a,l))*x;//求交集区间
add(a,b,x,k*2+1,l,(l+r)/2);
add(a,b,x,k*2+2,(l+r)/2,r);
}
}
//计算[a,b)的和
//k是结点的编号对应区间[l,r)
ll sum(int a,int b,int k,int l,int r){
if (b<=l||r<=a)
return 0;
else if (a<=l&&r<=b)
return data[k]*(r-l) + datb[k];
else{
ll res = (min(b,r)-max(a,l))*data[k];
res+= sum(a,b,k*2+1,l,(l+r)/2);
res+= sum(a,b,k*2+2,(l+r)/2,r);
return res;
}
}
int main(){
scanf("%d%d",&N,&Q);
for (int i=0;i<N;++i){
scanf("%d",&A[i]);
add(i,i+1,A[i],0,0,N);
}
while(Q--)
{
char s[5];
int a,b,c;
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d%d",&a,&b);
a-=1;b-=1;
printf("%I64d\n",sum(a,b+1,0,0,N));
}
else
{
scanf("%d%d%d",&a,&b,&c);
a-=1;b-=1;
add(a,b+1,c,0,0,N);
}
}
return 0;
}
poj3468线段树维护多个数据
最新推荐文章于 2021-09-29 18:56:03 发布