题目大意:
有N个格子,分别为1`N,M次修改,每次3个数Z,X,Y,
有2种情况:
Z=“M”时,将第X个格子加上Y。
Z=“C”时,统计区间[X,Y]的总和。
1≤N,M≤100000 1<=x<=y<=N
Z为M或者C
题解:
线段树:
1.可以发现,如果修改的话,每一次修改可以表示为在区间[l,l]加上一个数,这时候就用线段树。
2.每一次查询的时候,因为要修改的区间只有1个格子,所以这个区间一定是查询到的区间的一部分或者全部,这时候查询到区间[l,r]就给这个区间的总和加上修改的区间要添加的数,然后继续查询。
3.因为修改的区间都是线段树的最底端的几个点,所以不用做lazy,这对结果没有任何的影响,做了反而浪费时间。
var
tree:array [0..500001] of longint;
ans,i,n,m,x,y:longint;
s:char;
procedure insert(p,l,r,a:longint);
var
mid:longint;
begin
tree[p]:=tree[p]+y;
if l=r then exit;
mid:=(l+r) div 2;
if a<=mid then insert(p * 2,l,mid,a)
else insert(p*2+1,mid+1,r,a);
end;
procedure count(p,l,r,a,b:longint);
var
mid:longint;
begin
mid:=(l+r) div 2;
if (l=a) and (r=b)
then ans:=ans+tree[p]
else begin
if b<=mid then count(p * 2,l,mid,a,b)
else if a>mid then count(p*2+1,mid+1,r,a,b)
else begin
count(p * 2,l,mid,a,mid);
count(p*2+1,mid+1,r,mid+1,b);
end;
end;
end;
begin
readln(n);
readln(m);
for i:=1 to m do
begin
readln(s,x,y);
if s='M' then insert(1,1,n,x)
else begin
ans:=0;
count(1,1,n,x,y);
writeln(ans);
end;
end;
end.