题目链接
需要一层一层向上找到父节点并修改
for(int i=x;i<=n;i+=lowbit(i))t[i]+=k;
需要一层一层向左上寻找
int res=0; for(int i=x;i;i-=lowbit(i))res+=t[i]; return res;
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define pre(i,a,b) for(int i=(a);i>=(b);i--) #define close cin.tie(nullptr)->ios::sync_with_stdio(false) using namespace std; using ll =long long; const int N=5e5+10; int n,m; int t[N]; int lowbit(int x) { return x&-x; } void add(int x,int c) { for(int i=x;i<=n;i+= lowbit(i))t[i]+=c; } int query(int x) { int res=0; for(int i=x;i;i-= lowbit(i))res+=t[i]; return res; } void solve() { cin>>n>>m; rep(i,1,n){ int x;cin>>x; add(i,x); } while(m--) { int a,b,c; cin>>a>>b>>c; if(a==1)add(b,c); else cout<<query(c)-query(b-1)<<endl; } } int main() { close; // int _;cin>>_; // while(_--) solve(); return 0; }
题目链接
区间的修改 很容易想到用差分数组来实现 因此我们用树状数组来维护差分数组b[]的前缀和
差分数组的前缀和是原数组 因此我们要快速查询某一个点的值只需要求差分数组的前缀和即可
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define pre(i,a,b) for(int i=(a);i>=(b);i--) #define close cin.tie(nullptr)->ios::sync_with_stdio(false) using namespace std; using ll =long long; const int N=5e5+10; int n,m; int t[N]; int a[N],b[N]; int lowbit(int x) { return x&-x; } void add(int x,int c) { for(int i=x;i<=n;i+= lowbit(i))t[i]+=c; } int query(int x) { int res=0; for(int i=x;i;i-= lowbit(i))res+=t[i]; return res; } void solve() { cin>>n>>m; rep(i,1,n)cin>>a[i],b[i]=a[i]-a[i-1],add(i,b[i]); while(m--) { int op,x,y,k; cin>>op; if(op==1)cin>>x>>y>>k,add(x,k),add(y+1,-k); else if(op==2)cin>>x,cout<<query(x)<<endl; } } int main() { close; // int _;cin>>_; // while(_--) solve(); return 0; }