链接:点击打开链接
有N个数,A1~An,有两种操作,C A B C代表A到B区间所有的数都加C,Q A B是求A到B区间的和,是一道简单的成段更新,懒惰记忆。记得用long long就行
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 100010
struct node{
int l;
int r;
long long sum;
long long num;
}anode[4*N];
int data[N];
void bulid(int l,int r,int n){
int mid;
mid=(l+r)>>1;
anode[n].num=0;
if(l==r){
anode[n].l=l;
anode[n].r=r;
anode[n].sum=data[l];
}
else{
anode[n].l=l;
anode[n].r=r;
bulid(l,mid,2*n);
bulid(mid+1,r,2*n+1);
anode[n].sum=anode[2*n].sum+anode[2*n+1].sum;
}
}
long long query(int l,int r,int n,long long m){
int mid;
mid=(anode[n].l+anode[n].r)>>1;
if(anode[n].l==l&&anode[n].r==r){
return anode[n].sum+(r-l+1)*m;
}
if(r<=mid)
return query(l,r,2*n,m+anode[n].num);
else if(l>mid)
return query(l,r,2*n+1,m+anode[n].num);
else
return query(l,mid,2*n,m+anode[n].num)+query(mid+1,r,2*n+1,m+anode[n].num);
}
void update(int l,int r,int n,int m){
int mid;
mid=(anode[n].l+anode[n].r)>>1;
anode[n].sum+=(r-l+1)*m;
if(anode[n].l==l&&anode[n].r==r){
anode[n].num+=m;
return;
}
if(r<=mid)
update(l,r,2*n,m);
else if(l>mid)
update(l,r,2*n+1,m);
else{
update(l,mid,2*n,m);
update(mid+1,r,2*n+1,m);
}
}
int main(){
int n,q,a,b,c,i;
char str;
while(~scanf("%d %d",&n,&q)){
for(i=1;i<=n;i++)
scanf("%d",&data[i]);
bulid(1,n,1);
//getchar();
while(q--){
getchar();
scanf("%c",&str);
if(str=='Q'){
scanf("%d %d",&a,&b);
printf("%lld\n",query(a,b,1,0));
}
else if(str=='C'){
scanf("%d %d %d",&a,&b,&c);
update(a,b,1,c);
}
}
}
return 0;
}