[CodeVS1081]线段树练习2(区间修改+单点询问)

来源:互联网 发布:杀破狼原唱js 编辑:程序博客网 时间:2024/05/16 16:07

线段树练习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.
0 0
原创粉丝点击