POJ3468 - A Simple Problem with Integers
题目大意
给定N个整数,A1,A2,A3…An。可以对这些数进行一下两种操作:
1、"C a b c" 对区间[a,b]内的所有数都加上c
2、"Q a b"询问区间[a,b]的和
题解
一般树状数组都是实现单点修改和区间求和或者单点查询和区间加减的功能,而此题是要求实现区间查询,区间加减的功能,我们依然能够用树状数组来处理,具体怎么处理请参看wyl神牛的树状数组总结吧
代码:
#include<iostream> #include<cstring> #include<cstdio> #define MAXN 100005 long long a[MAXN],c[MAXN],b[MAXN]; int n,m; using namespace std; int lowbit(int x) { return x&-x; } void add(long long a[],int x,int d) { while(x<=n) { a[x]+=d; x+=lowbit(x); } } long long sum(long long a[],int x) { long long ret=0; while(x>0) { ret+=a[x]; x-=lowbit(x); } return ret; } int main(void) { int i,l,r,d; long long ans; char ch; while(scanf("%d%d",&n,&m)!=EOF) { memset(c,0,sizeof(c)); memset(b,0,sizeof(b)); a[0]=0; for(i=1; i<=n; i++) { scanf("%lld",&a[i]); a[i]+=a[i-1]; } for(i=1; i<=m; i++) { getchar(); scanf("%c",&ch); if(ch=='C') { scanf("%d%d%d",&l,&r,&d); add(b,l,d); add(b,r+1,-d); add(c,l,d*l); add(c,r+1,-(r+1)*d); } else { scanf("%d%d",&l,&r); ans=a[r]-a[l-1]+(r+1)*sum(b,r)-l*(sum(b,l-1))-sum(c,r)+sum(c,l-1); printf("%lld\n",ans); } } } return 0; }