题目描述 Description
一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。
输入描述 Input Description
输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。
输出描述 Output Description
共m行,每个整数
样例输入 Sample Input
6
4
5
6
2
1
3
4
1 3 5
2 1 4
1 1 9
2 2 6
样例输出 Sample Output
22
22
找了一会儿bug
changed里面 递归到最深处时 应该修改tr[now].sumc
手胡写成tr[sum].l
找了很久
时间证明debug()函数是个好东西啊…
以及题解里面的线段树看不懂…
逼着自己写…
#include<bits/stdc++.h>
#define maxn 100001
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
int n,m;
int a[maxn];
struct node{
int l,r,lc,rc,sumc;
}tr[maxn*2]; int len;
void debug(){
for(int i=1;i<=len;++i)
cout<<i<<": "<<tr[i].l<<" "<<tr[i].r<<" "<<tr[i].lc<<" "<<tr[i].rc<<" "<<tr[i].sumc<<endl;
}
void bt(int l,int r){
++len;int now=len;
tr[now].l=l,tr[now].r=r;
tr[now].lc=tr[now].rc=-1;
if(l==r) tr[now].sumc=a[l];
else{
int mid=(tr[now].l+tr[now].r)>>1;
tr[now].lc=len+1,bt(l,mid);
tr[now].rc=len+1,bt(mid+1,r);
if(tr[now].l!=tr[now].r) tr[now].sumc=tr[tr[now].lc].sumc+tr[tr[now].rc].sumc;
}
}
void changed(int now,int x,int k){
if(tr[now].l==tr[now].r&&tr[now].l){
tr[now].sumc+=k;
return;
}
int mid=(tr[now].l+tr[now].r)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
if(x<=mid) changed(lc,x,k);
else if(x>=mid+1) changed(rc,x,k);
if(tr[now].l!=tr[now].r) tr[now].sumc=tr[lc].sumc+tr[rc].sumc;
}
int findsum(int now,int l,int r){
if(tr[now].l==l&&tr[now].r==r) return tr[now].sumc;
int mid=(tr[now].l+tr[now].r)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
if(r<=mid) return findsum(lc,l,r);
else if(l>=mid+1) return findsum(rc,l,r);
else return ( findsum(lc,l,mid)+findsum(rc,mid+1,r) );
}
int main(){
read(n);
for(int i=1;i<=n;++i) read(a[i]);
bt(1,n);
read(m);
for(int i=1;i<=m;++i){
int ti,x,y;
read(ti),read(x),read(y);
if(ti==1) changed(1,x,y);
else{
if(x>y) swap(x,y);
cout<<findsum(1,x,y)<<endl;
}
/*cout<<"i="<<i<<": "<<endl;
debug();*/
}
return 0;
}