线段树练习五
Description
一行N个方格,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤100000,提问和修改的总数可能达到100000条。
Input
20
6
M 1 1
M 2 2
M 3 4
M 3 -5
M 6 7
C 2 6
Output
8
解题思路
这道题也只是比较简单的一道题,和前几道题的区别是:1.需要更新父节点。2.对点的判定有所区别。代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
struct abc{
int x,y,sum;
}tree[400010];
void build(int u,int x,int y)
{
tree[u].x=x;
tree[u].y=y;
if(x==y) return;
int mid=(x+y)/2;
build(u*2,x,mid);
build(u*2+1,mid+1,y);
}
void in(int u,int t,int s)
{
if(tree[u].x==t&&tree[u].y==t)
{
tree[u].sum+=s;
return;
}
else if(t<=tree[u*2].y)
in(u*2,t,s);
else
in(u*2+1,t,s);
tree[u].sum=tree[u*2].sum+tree[u*2+1].sum;
}
int find(int u,int l,int r)
{
if(tree[u].x==l&&tree[u].y==r)
return tree[u].sum;
if(r<=tree[u*2].y)
return find(u*2,l,r);
else
if(l>=tree[u*2+1].x)
return find(u*2+1,l,r);
else
return find(u*2,l,tree[u*2].y)+find(u*2+1,tree[u*2+1].x,r);
}
int main()
{
scanf("%d%d", &n, &m);
tree[1].x=1;
tree[1].y=n;
build(1,1,n);
for(int i=1;i<=m;i++)
{
char t;
int a,b;
cin>>t;
scanf("%d%d",&a,&b);
if(t=='M')
in(1,a,b);
else
printf("%d\n", find(1, a, b));
}
}