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

线段树练习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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值