线段树
线段树
代码(建树):
void create(int l,int r,int u) {
if(l==r) {
a[u]=x[l];
return;
} int mid=l+r>>1;
create(l,mid,u<<1), create(mid+1,r,u<<1|1);
a[u]=a[u<<1]+a[u<<1|1];
} //to create a tree
代码(查询)
int query(int l,int r,int u,int s,int t) {
if(s>r||t<l) return 0;
if(l>=s&&r<=t) return a[u];
int mid=(l+r)>>1;
return query(l,mid,u<<1,s,t)+query(mid+1,r,u<<1|1,s,t);
}
代码(修改)
void upd(int l,int r,int u,int i,int c) {
a[u]+=c;
if(l==r) return;
int mid=l+r>>1;
if(mid>=i) upd(l,mid,u<<1,i,c);
else upd(mid+1,r,u<<1|1,i,c);
}
完整代码:
#include<iostream>
#define int long long
using namespace std;
const int N = 1e6+7;
int a[N<<2],x[N];
void create(int l,int r,int u) {
if(l==r) {
a[u]=x[l];
return;
} int mid=l+r>>1;
create(l,mid,u<<1), create(mid+1,r,u<<1|1);
a[u]=a[u<<1]+a[u<<1|1];
} //to create a tree
int query(int l,int r,int u,int s,int t) {
if(s>r||t<l) return 0;
if(l>=s&&r<=t) return a[u];
int mid=(l+r)>>1;
return query(l,mid,u<<1,s,t)+query(mid+1,r,u<<1|1,s,t);
}
//this function refers to query the [l,r] period on the tree whose root is u.
void upd(int l,int r,int u,int i,int c) {
a[u]+=c;
if(l==r) return;
int mid=l+r>>1;
if(mid>=i) upd(l,mid,u<<1,i,c);
else upd(mid+1,r,u<<1|1,i,c);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>x[i];
create(1,n,1);
while(m--) {
int op,e,f;
cin>>op>>e>>f;
if(op==2) cout<<query(1,n,1,e,f)<<'\n';
else upd(1,n,1,e,f);
}
return 0;
}
输入
16 7
9 1 3 0 4 5 7 6 8 0 3 3 2 8 1 4
1 6 9
2 1 8
1 11 3
2 5 11
1 7 5
1 1 10
2 7 15
输出:
44
45
46
例题:https://www.luogu.com.cn/problem/P4513
代码:https://www.codepaste.cn/#/cd/fc2100ac-9167-46b3-9473-a809bf772f5d