[线段树]线段树练习五
线 段 树 练 习 题 五 线段树练习题五 线段树练习题五
题目描述
一行N个方格,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤100000,提问和修改的总数可能达到100000条。
样例输入
20 //方格个数
6 //有几组操作
M 1 1 //表示修改,第一个表示格子位置,第二个数表示在原来的基础上加上的数,
M 2 2
M 3 4
M 3 -5
M 6 7
C 2 6 //表示统计 ,第一个数表示起始位置,第二个数表示结束位置
样例输出
8
数据范围
N <= 10000
M <= 1000000
code
#include<stdio.h>
#include<iostream>
using namespace std;
char c;
int n,m,e,z,tr[400005]={0};
void insertt(int t,int a,int b);
int countt(int t,int x,int y,int a,int b);
int main(){
scanf("%d%d ",&m,&n);
for(int i=1;i<=n;i++){
cin>>c;
scanf("%d%d",&e,&z);
if(c=='M')insertt(1,1,m);
else{
printf("%d\n",countt(1,1,m,e,z));
}
}
return 0;
}
int countt(int t,int x,int y,int a,int b){
if(y>m)return 0;
if(x==a and y==b){
return tr[t];
}
int mid=(x+y)/2;
if(b<=mid){
return countt(t*2,x,mid,a,b);
}
else if(a>mid){
return countt(t*2+1,mid+1,y,a,b);
}
else{
return countt(t*2,x,mid,a,mid)+countt(t*2+1,mid+1,y,mid+1,b);
}
}
void insertt(int t,int a,int b){
if(a==b){
tr[t]+=z;
return ;
}
int mid=(a+b)/2;
if(e<=mid){
insertt(t*2,a,mid);
}
else{
insertt(t*2+1,mid+1,b);
}
tr[t]+=z;
}