数列分块入门 1
题目分析
考虑先差分,相当于给
不知道如何维护?移步我的树状数组题解。
由于被管理员拒绝了,这里把部分我自己题解内容搬运过来。
题目要求我们在较快的时间内实现单点加、区间查询。
如果我们正常做,若干次
如果前缀和的话,修改操作需要恢复数组,也很慢。
如果使用差分,查询也要很长时间。
考虑使用树状数组,它的结构大体如下:
我们知道
我们让
我们考虑单点修改:对于一个点
考虑查询:
考虑处理其中一部分:求
我们考虑到必须要取
但是
时间复杂度:考虑跳
时间复杂度
双倍经验。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int N=3e5+2;
int n,q,f[N];
void add(int x,int k){
#define lowbit(x) ((x)&(-(x)))
for(;x<=n;x+=lowbit(x))
f[x]+=k;
return;
#undef lowbit
}
int qry(int x){
#define lowbit(x) ((x)&(-(x)))
int ret=0;
for(;x;x-=lowbit(x))
ret+=f[x];
return ret;
#undef lowbit
}
signed main(){
cin>>n;
q=n;
for(int i=1,ai;i<=n;i++){
cin>>ai;
add(i,ai),add(i+1,-ai);
}
for(int op,l,r,x;q;--q){
cin>>op>>l>>r>>x;
if(!op)
add(l,x),add(r+1,-x);
else
cout<<qry(r)<<'\n';
}
return 0;
}