树状数组
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 100010;
int a[N],c[N];//a是原数组,c是新数组
int n, m;
int lobit(int x)
{
return x & -x;
}
void add(int x, int y)
{
for (int i = x; i <= n; i += lobit(i))//求出y总讲的c数组
c[i] += y;
}
int sum(int x)//求前缀和数组
{
int rest = 0;
for (int i = x;i;i -= lobit(i))
{
rest += c[i];//动态的过程,不用另开数组
}
return rest;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1;i <= n;i++)
{
scanf("%d", &a[i]);//得到原数组
add(i,a[i]);//将原数组加给c数组
}
while (m--)
{
int k, l, r;
scanf("%d%d%d",&k,&l,&r);
if (k == 0) printf("%d\n",sum(r) - sum(l - 1));//动态求区间和
else add(l,r);//加上那个数
}return 0;
}
线段树
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=100010;
int n,m;
int c[N];
struct node{
int l,r;
int sum;
}tr[N*4];
void pushup(int u)
{
tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{
if(l==r)tr[u]={l,r,c[l]};
else
{
int mid=l+r>>1;
tr[u]={l,r};
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
pushup(u);
}
}
int research(int u,int l,int r)
{
if(l<=tr[u].l&&r>=tr[u].r)return tr[u].sum;
int sum=0;
int mid=tr[u].r+tr[u].l>>1;
if(l<=mid)sum+=research(u<<1,l,r);
if(r>mid)sum+=research(u<<1|1,l,r);
return sum;
}
void revise(int u,int l,int r)
{
if(tr[u].l==tr[u].r)tr[u].sum+=r;
else
{
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)revise(u<<1,l,r);
else revise(u<<1|1,l,r);
pushup(u);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
build(1,1,n);
int k,a,b;
while(m--)
{
scanf("%d%d%d",&k,&a,&b);
if(!k)cout<<research(1,a,b)<<endl;
else revise(1,a,b);
}
return 0;
}
大佬你好