线段树练习2
题目描述 Description
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入描述 Input Description
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出描述 Output Description
对于每个询问输出一行一个答案
样例输入 Sample Input
3
1
2
3
2
1 2 3 2
2 3
样例输出 Sample Output
5
数据范围及提示 Data Size & Hint
1<=n<=100000
1<=q<=100000
var
w:array[0..400005,1..4]of longint;
x:array[0..100000]of longint;
i,j,k:longint;
n,m:longint;
a,b,c,d:longint;
procedure build(a,l,r:longint);
var mid:longint;
begin
w[a,1]:=l; w[a,2]:=r;
if l=r then begin w[a,3]:=x[l]; exit; end;
mid:=(l+r)div 2;
build(a*2,l,mid);
build(a*2+1,mid+1,r);
end;
procedure update(a,l,r:longint);
var mid:longint;
begin
if (w[a,1]=l)and(w[a,2]=r)
then begin inc(w[a,3],d); exit; end;
mid:=(w[a,1]+w[a,2])div 2;
if r<=mid
then update(a*2,l,r) else
if l>mid
then update(a*2+1,l,r) else
begin
update(a*2,l,mid);
update(a*2+1,mid+1,r);
end;
end;
function query(a,b:longint):longint;
var mid:longint;
begin
if (w[a,1]<>w[a,2])and(w[a,3]<>0) then begin inc(w[a*2,3],w[a,3]); inc(w[a*2+1,3],w[a,3]); w[a,3]:=0; end;
if (w[a,1]=w[a,2])and(w[a,1]=b)
then exit(w[a,3]);
mid:=(w[a,1]+w[a,2])div 2;
if b<=mid
then exit(query(a*2,b))
else exit(query(a*2+1,b));
end;
begin
readln(n);
for i:=1 to n do
readln(x[i]);
build(1,1,n);
readln(m);
for i:=1 to m do
begin
read(a);
if a=1
then begin readln(b,c,d); update(1,b,c); end
else begin readln(b); writeln(query(1,b)); end;
end;
end.