线段树———模板
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int const maxn=100010; int tot=0,a[maxn]={0}; int n,m; struct treetype { int left,right; //左右区间 int letr,ritr; //左右孩子 int sum; //区间和 } t[maxn*2]; void buildtree(int ll,int rr) //建树 { int tur=++tot; //结点代号 t[tur].left=ll; t[tur].right=rr; if (ll!=rr-1) { t[tur].letr=tot+1; buildtree(ll,(ll+rr)/2); t[tur].ritr=tot+1; buildtree((ll+rr)/2,rr); t[tur].sum=t[t[tur].letr].sum+t[t[tur].ritr].sum; } else t[tur].sum=a[ll]; } void change(int k,int x,int y) //更改 { if (t[k].left==t[k].right-1) t[k].sum+=y; else { if (x<(t[k].left+t[k].right)/2) change(t[k].letr,x,y); if (x>=(t[k].left+t[k].right)/2) change(t[k].ritr,x,y); t[k].sum=t[t[k].letr].sum+t[t[k].ritr].sum; } } int summ(int k,int ll,int rr) //求区间和 { if (ll<=t[k].left && rr>=t[k].right) //如果 目前区间 在 要求的区间 内,那么直接返回目前区间和, return t[k].sum; //因为 目前区间 的和一定属于 要求的区间和 int ans=0; //记录区间和 if (ll<(t[k].left+t[k].right)/2) ans+=summ(t[k].letr,ll,rr); if (rr>(t[k].left+t[k].right)/2) ans+=summ(t[k].ritr,ll,rr); return ans; //找(n,m)区间和,那么二分查找各个分区间的和,将值返回累加 } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) cin>>a[i]; buildtree(1,n+1); scanf("%d",&m); for (int i=1;i<=m;i++) { int c,p,k; scanf("%d%d%d",&c,&p,&k); if (c==1) change(1,p,k); if (c==2) printf("%d\n",summ(1,p,k+1)); //要给查找的区间加上1,查找n—>m就要查(n,m+1) } //找了半个小时不同TMD !!! } //【1,n)前闭后开