小明的练习题1
题目描述
给你N个数,有两种操作
1:给区间[a,b]的所有数都增加X
2:询问第i个数是什么?
输入
第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数。如果第一个数是1,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是2,后面跟1个整数i, 表示询问第i个位置的数是多少。
输出
对于每个询问输出一行一个答案
样例输入
3
1
2
3
2
1 2 3 2
2 3
样例输出
5
提示
1<=n<=100000
1<=q<=100000
中间过程不会超过longint
分析
这道题用的是差分思想。
设d[0]=0,a[0]=0,
d[i]=a[i]-a[i-1];
d[1]=a[1]-a[0]
d[2]=a[2]-a[1]
d[3]=a[3]-a[2]
d[4]=a[4]-a[3]
…
d[x]=a[x]-a[x-1]
[l,r]+x 只用改变d[l]+x与d[r+1]-x, 区间修改转化为单点修改。
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
var
n,q,i,j,k,x,y,p:
longint
;
a,c:
array
[
1..100005
]
of
longint
;
function
lowbit(x:
longint
):
longint
;
begin
exit(x
and
(-x));
end
;
procedure
add(x,y:
longint
);
begin
while
x<=n
do
begin
c[x]:=c[x]+y;
x:=x+lowbit(x);
end
;
end
;
function
sum(x:
longint
):
longint
;
var
ans:
longint
;
begin
ans:=
0
;
while
x>
0
do
begin
ans:=ans+c[x];
x:=x-lowbit(x);
end
;
exit(ans);
end
;
begin
readln(n);
for
i:=
1
to
n
do
begin
readln(a[i]);
add(i,a[i]-a[i-
1
]);
end
;
readln(q);
for
i:=
1
to
q
do
begin
read(k);
if
k=
1
then
begin
readln(x,y,p);
add(x,p);
add(y+
1
,-p);
end
else
begin
readln(x);
writeln
(sum(x));
end
;
end
;
end
.
|