作为一个初学线段树的蒟蒻,赶快来瞻仰一下
线段树模板题(一)——单点修改与查询区间和:快速求和计算
【题目描述】
给出n个数(1 < = n < = 100000 ),并且初始化所有数字都为0.接下来m次操作,( 1<= m < = 100000 ) 操作有以下两种:
1: C X K 把第X个数的值增加A(A可正可负)
2: P X Y 就是询问 第X个数至 第Y个数 的所有数的和。
【输入】
n m 若干操作
【输出】
对应的输出
【样例输入】
5 3
C 2 3
C 4 5
P 1 5
【样例输出】
8
代码:
#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define lc (p<<1)
#define rc (p<<1|1)
int n,m;
struct node{
int l,r,sum;
}T[4*N];
void pushup(int p){
T[p].sum=T[lc].sum+T[rc].sum;
}
void build(int p,int l,int r){//建树
T[p].l=l;T[p].r=r;
if(l==r){
T[p].sum=0;
return ;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
}
void update(int p,int k,int v){//单点修改
if(T[p].l==T[p].r){
T[p].sum+=v;
return ;
}
int mid=(T[p].l+T[p].r)>>1;
if(k<=mid)
update(lc,k,v);
else
update(rc,k,v);
pushup(p);
}
int query(int p,int ql,int qr){//区间求和
if(ql<=T[p].l&&qr>=T[p].r)
return T[p].sum;
int mid=T[p].l+T[p].r>>1;
int ans=0;
if(ql<=mid) ans+=query(lc,ql,qr);
if(qr>mid) ans+=query(rc,ql,qr);
return ans;
}
int main(){
scanf("%d%d",&n,&m);
build(1,1,100010);
for(int i=1;i<=m;i++){
char p;
cin>>p;
if(p=='C'){
int x,k;
scanf("%d%d",&x,&k);
update(1,x,k);
}
else{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",query(1,x,y));
}
}
return 0;
}