维持一个整数序列,支持2种操作:
Q a b:查询区间[a,b]内的和;
C a b x:将区间[a,b]内的每个数加上x。
对于每次查询输出结果。
结果可能会超32位。
#include <stdio.h> #define N 100001 int n,m,a[N]; long long ans; long long sum[4*N],inc[4*N]; void update(int cur) { int ls=cur<<1,rs=cur<<1|1; sum[cur]=sum[ls]+sum[rs]; } void pushdown(int cur,int x,int y) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(inc[cur]) { sum[ls]+=inc[cur]*(mid-x+1); sum[rs]+=inc[cur]*(y-mid); inc[ls]+=inc[cur]; inc[rs]+=inc[cur]; inc[cur]=0; } } void build(int cur,int x,int y) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; inc[cur]=0; if(x==y) { sum[cur]=a[x]; return; } build(ls,x,mid); build(rs,mid+1,y); update(cur); } void change(int cur,int x,int y,int s,int t,int v) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(x>=s && y<=t) { sum[cur]+=v*(y-x+1); inc[cur]+=v; return; } pushdown(cur,x,y); if(mid>=s) change(ls,x,mid,s,t,v); if(mid+1<=t) change(rs,mid+1,y,s,t,v); update(cur); } void query(int cur,int x,int y,int s,int t) { int mid=(x+y)>>1,ls=cur<<1,rs=cur<<1|1; if(x>=s && y<=t) { ans+=sum[cur]; return; } pushdown(cur,x,y); if(mid>=s) query(ls,x,mid,s,t); if(mid+1<=t) query(rs,mid+1,y,s,t); } int main() { int i,x,y,z; char c; while(~scanf("%d%d",&n,&m)) { for(i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); for(i=0;i<m;i++) { c=0; while(c!='Q' && c!='C') scanf("%c",&c); scanf("%d%d",&x,&y); if(c=='Q') { ans=0; query(1,1,n,x,y); printf("%lld\n",ans); } else { scanf("%d",&z); change(1,1,n,x,y,z); } } } return 0; }