洛谷P3374 【模板】树状数组 1题解

作为一个萌新,在自学新知识的时候回遇到一些困难。在还没有学习树状数组的情况下,初学没有down的线段树……~~所以这篇题解是给初学线段树的同学分享一下经验的~~

如果你还不知道线段树是什么,看转载https://www.cnblogs.com/jason2003/p/9676729.html

很多内容在转载的博客中都有详细解释,下面只是一个简单归纳

```cpp
#include <bits/stdc++.h>
#define MAXN 2000001
#define ll long long
using namespace std;

int n,m,a[MAXN];

inline int gin(){//快读
char c=getchar();
int s=0,f=1;
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
s=(s<<3)+(s<<1)+(c^48);
c=getchar();
}
return s*f;
}

struct data{//习惯用结构体来编写
int l,r;
int sum;
}tree[MAXN];

void build(int i,int l,int r){//建树
tree[i].l=l;tree[i].r=r;
if(l==r){
tree[i].sum=a[l];
return;
}
int mid=l+r>>1;
build(2*i,l,mid);
build(2*i+1,mid+1,r);
tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
}

void add(int i,int dis,int k){//单点修改
if(tree[i].l == tree[i].r){
tree[i].sum+=k;
return;
}
if(dis<=tree[2*i].r)add(2*i,dis,k);
else add(2*i+1,dis,k);
tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
return;
}

inline int search(int i,int l,int r){//区间查询
if(tree[i].l>=l && tree[i].r<=r){
return tree[i].sum;
}
if(tree[i].r<l || tree[i].l>r)return 0;
int s=0;
if(tree[2*i].r>=l)s+=search(2*i,l,r);
if(tree[2*i+1].l<=r)s+=search(2*i+1,l,r);
return s;
}

int main(){
n=gin(),m=gin();
for(int i=1;i<=n;i++){
a[i]=gin();
}
build(1,1,n);
for(int i=1;i<=m;i++){
int c=gin(),x=gin(),y=gin();
//分类
if(c==1){
add(1,x,y);
}
else if(c==2){
printf("%d\n",search(1,x,y));
}
}
return 0;
}

```

猜你喜欢

转载自www.cnblogs.com/wzsyyh/p/12501764.html