题目1 easy version
题目2 hard version
题意辨析
这两道题区别在于easy version是将某一个数加上了x,而hard version是将每一个数都加上了x,虽然最后都让求的区间和…
思路
题目一当然简单了,开一个树状数组tree直接记录一下tree[l]+=x
tree[r+1]-=x
这样到最后用前缀和算一遍就直接出来了思维量还是比较低的
#include<iostream>
using namespace std;
const int N=5e5+7;
int s[N];
int tree[N];
int lowbit(int x){
return x&(-x);
}
void add(int a,int b){
for(int i=a;i<=N;i+=lowbit(i)){
tree[i]+=b;
}
return;
}
int query(int x){
int res=0;
for(int i=x;i;i-=lowbit(i)){
res+=tree[i];
}
return res;
}
int query(int x,int y){
return query(y)-query(x-1);
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
int u;
cin>>u;
s[i]+=s[i-1]+u;
}
for(int i=1;i<=m;i++){
int q;
cin>>q;
if(q==1){
int a,b;
cin>>a>>b;
add(a,b);
}else {
int a,b;
cin>>a>>b;
cout<<s[b]-s[a-1]+query(a,b)<<endl;
}
}
}
但是题目二就需要用到我们之前讲过的差分的知识了
#include<iostream>
using namespace std;
typedef long long ll;
const int N=5e5+7;
ll s[N];
ll tree1[N];
ll tree2[N];
ll a[N];
ll lowbit(ll x){
return x&(-x);
}
void add(ll tree[],int a,ll b){
for(int i=a;i<=N;i+=lowbit(i)){
tree[i]+=b;
}
return;
}
ll query(ll tree[],int x){
ll res=0;
for(int i=x;i;i-=lowbit(i)){
res+=tree[i];
}
return res;
}
ll query(int x){
return query(tree1,x)*(x+1)-query(tree2,x);
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
add(tree1,i,a[i]-a[i-1]);
add(tree2,i,(a[i]-a[i-1])*i);
}
for(int i=1;i<=m;i++){
char q;
getchar();
cin>>q;
if(q=='C'){
ll l,r,c;
cin>>l>>r>>c;
//a[l]+=c;
add(tree1,l,c); add(tree2,l,l*c);
//a[r+1]-=c;
add(tree1,r+1,-c); add(tree2,r+1,-(r+1)*c);
}else {
ll l,r;
cin>>l>>r;
cout<<query(r)-query(l-1)<<endl;
}
}
}