#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>usingnamespace std;constint N =100010;int n, m;int a[N], tr[N];intlowbit(int x){//取x的最后一位1return x&-x;}voidadd(int x,int y){//在x处加上yfor(int i=x;i<=n;i+=lowbit(i)){
tr[i]+=y;}}intquery(int x){//查询第x位置的前缀和int res=0;for(int i=x;i;i-=lowbit(i))res+=tr[i];return res;}intmain(){scanf("%d%d",&n,&m);for(int i =1; i <= n; i ++)scanf("%d",&a[i]);for(int i =1; i <= n; i ++)add(i, a[i]);while(m --){int k, x, y;scanf("%d%d%d",&k,&x,&y);if(k ==0)printf("%d\n",query(y)-query(x -1));elseadd(x, y);}return0;}
线段树
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>usingnamespace std;constint N =100010;int n, m;int w[N];struct Node
{int l, r;int sum;}tr[N *4];voidpushup(int u)//更新u节点的sum值{
tr[u].sum = tr[u <<1].sum + tr[u <<1|1].sum;}voidbuild(int u,int l,int r)//创建u节点,区间为l,r的树{if(l == r) tr[u]={l, r, w[r]};//如果已经是叶节点了,就直接赋值else{
tr[u]={l, r};int mid = l + r >>1;build(u <<1, l, mid),build(u <<1|1, mid +1, r);pushup(u);}}intquery(int u,int l,int r){if(tr[u].l >= l && tr[u].r <= r)return tr[u].sum;//如果节点在查询区间内部,就直接返回sumint mid = tr[u].l + tr[u].r >>1;int sum =0;//判断是否在u的左右子树中if(l <= mid) sum =query(u <<1, l, r);if(r > mid) sum +=query(u <<1|1, l, r);return sum;}voidmodify(int u,int x,int v){if(tr[u].l == tr[u].r) tr[u].sum += v;//如果已经是叶节点了,就直接修改sumelse{int mid = tr[u].l + tr[u].r >>1;if(x <= mid)modify(u <<1, x, v);elsemodify(u <<1|1, x, v);pushup(u);//在修改完u下的子节点后,再更新u}}intmain(){scanf("%d%d",&n,&m);for(int i =1; i <= n; i ++)scanf("%d",&w[i]);build(1,1, n);int k, a, b;while(m --){scanf("%d%d%d",&k,&a,&b);if(k ==0)printf("%d\n",query(1, a, b));elsemodify(1, a, b);}return0;}