题目链接http://poj.org/problem?id=3468
题目大意:
就是给你一列数字,然后进行区间的加相对应的数的操作,要你能够输出指定区间内的和。
思路:
这道题按理来说是要用线段树的,但我这里讲的是树状数组的思路。
然后呢,从树状数组的角度出发,这个问题其实本质上就是“树形数组里的区间更新,区间查询”。
这个思路的讲解已经有大佬写的很详细了,附上大佬链接:
https://www.cnblogs.com/xenny/p/9739600.html
对了,差点忘记说了。这题有个坑,就是所有的数值最好都用long long 类型,不然就会wrong answer。。。
ac代码:
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 100005;
typedef long long ll;
ll a[maxn];
ll sum1[maxn];//D[1]+D[2]+...+D[n]
ll sum2[maxn];//0*D[1]+1*D[2]+...+(n-1)*D[n]
ll n;
//********下面是树形数组操作********
int lowbit(ll x){
return x&(-x);
}
void update(ll i,ll k){
ll x = i;
while(i <= n){
sum1[i] += k;
sum2[i] += k*(x-1);
i += lowbit(i);
}
}
ll getsum(int i){
ll ans = 0;
ll x = i;
while(i > 0){
ans += x*sum1[i] - sum2[i];
i -= lowbit(i);
}
return ans;
}
//********上面是树形数组操作********
int main(){//树形数组:区间更新,区间查询
ll m;
cin>>n>>m;
memset(a,0,sizeof(a));
memset(sum1,0,sizeof(sum1));
memset(sum2,0,sizeof(sum2));
for(ll i = 1;i <= n;i++){
cin>>a[i];
update(i,a[i]-a[i-1]);
}
char ch;
ll a,b,c;
ll sum;
while(m--){
cin>>ch;
if(ch == 'Q'){
cin>>a>>b;
sum = getsum(b) - getsum(a-1);
cout<<sum<<endl;
}else if(ch == 'C'){
cin>>a>>b>>c;
update(a,c);
update(b+1,-c);
}
}
return 0;
}