[POJ 3468] A Simple Problem with Integers [树状数组]

来源:互联网 发布:网络连接权限控制 编辑:程序博客网 时间:2024/05/05 14:13

给一列数,有区间修改区间查询,线段树模板题。

使用树状数组的区间修改区间查询版本..

设原数组为a[],现记录b[i]为原数组中a[1]...a[i]整体被加了多少,c[i]为原书组中a[1]...a[i]整体被加了多少的和,即c[i]=b[i]*i。

进行区间修改[l,r]时,只需让b[r]+=x,b[l-1]-=x即可,对应的c[i]的变化量为b[i]*i。

进行区间查询[1,l]时,只需计算c[1]+c[2]+...+c[l]+(b[l+1]+b[l+2]+...+b[n])*l即可。

#include <cstring>#include <cstdio>struct BIT {int n;long long b[100002];long long c[100002];void clear(int nn) {n=nn;for (int i=0;i<=n;i++) b[i]=c[i]=0;}inline int lb(int i) {return i&-i;}void set(long long a[],int i,long long x) {if (i==0) return;for (;i<=n;i+=lb(i)) a[i]+=x;}long long get(long long a[],int i) {long long ans=0;for (;i>0;i-=lb(i)) ans+=a[i];return ans;}void set(int x,int y,long long z) {set(b,y,z);set(b,x-1,-z);set(c,y,z*y);set(c,x-1,-z*(x-1));}long long get(int i) {return get(c,i)+(get(b,n)-get(b,i))*i;}};int n,q;BIT c;int main() {int i,x,y,z;char cc;scanf("%d%d",&n,&q);c.clear(n);for (i=1;i<=n;i++) {scanf("%d",&x);c.set(i,i,x);}while (q--) {scanf(" %c",&cc);if (cc=='C') {scanf("%d%d%d",&x,&y,&z);c.set(x,y,z);} else {scanf("%d%d",&x,&y);printf("%lld\n",c.get(y)-c.get(x-1));}}return 0;}


0 0
原创粉丝点击