您的位置:首页 > 其它

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

2014-07-25 15:58 513 查看
给一列数,有区间修改区间查询,线段树模板题。

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

设原数组为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
)*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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: