区间增加+单点查询
题目类型:
给定长度为n的数组a,q次操作。
第一类操作:“C l r d” 表示把区间[l,r]中的数加上d
第二类操作:“Q x” 表示求第x个数的值
思路:利用差分的思想,引入差分数组b,将[l,r]内的数加上d,也就是将b[l]加d,b[r+1]减去d,而要求第x个数,也就是求,而对于b也就是单点增加操作,每次对l加d,对r+1加-d,可以利用树状数组维和b的前缀和。也就将问题转化为了单点增加+单点查询
区间增加+区间查询
http://poj.org/problem?id=3468
#include <iostream>
#include <algorithm>
#include <stdio.h>
//#include <bits/stdc++.h>
#define ll long long
const int N = 1e6+7;
const int mod = 1e9+7;
const double eps = 1e-8;
using namespace std;
ll pre[N],a[N],c[2][N];
int n;
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int k){
while(x <= n){
c[k][x] += 1ll*y;
x += lowbit(x);
}
}
ll query(int x,int k){
ll res = 0;
while(x){
res += c[k][x];
x -= lowbit(x);
}
return res;
}
void solve(){
int q,x,y,z;
char c;
scanf("%d%d",&n,&q);
for(int i = 1; i <= n; i++){
scanf("%lld",&a[i]);
pre[i] = pre[i-1]+a[i];
}
while(q--){
scanf(" %c",&c);
if(c == 'C'){
scanf("%d%d%d",&x,&y,&z);
add(x,z,0);
add(y+1,-z,0);
add(x,x*z,1);
add(y+1,-(y+1)*z,1);
}
else{
scanf("%d%d",&y,&x);
ll ans = 0;
ans = (pre[x]+(x+1)*query(x,0)-query(x,1))-(pre[y-1]+(y)*query(y-1,0)-query(y-1,1));
cout << ans << endl;
}
}
}
int main(){
// int t;
// cin >> t;
// while(t--)
solve();
system("pause");
return 0;
}