备战2024年蓝桥杯 -- 每日一题
Python大学A组
试题一:【模板】树状数组1
【题目描述】
如题,已知一个数列,你需要进行下面两种操作:
-
将某一个数加上 x
-
求出某区间每一个数的和
【输入格式】
第一行包含两个正整数n,m,分别表示该数列数字的个数和操作的总个数。
第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 m 行每行包含 3 个整数,表示一个操作,具体如下:
-
1 x k
含义:将第 x 个数加上 k -
2 x y
含义:输出区间 [x,y] 内每个数的和
【输出格式】
输出包含若干行整数,即为所有操作 2 的结果。
【输入样例】
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
【输出样例】
14
16
【解题思路】
点修区间查,模板题
【Python程序代码】
python
n,m = map(int,input().split())
a = [0] + list(map(int,input().split()))
s = [0]* (len(a)+5)
def lowbit(x):
return x&-x
def add(i,x):
while i<=n:
s[i]+=x
i += lowbit(i)
def quary(x):
res = 0
while x:
res += s[x]
x -= lowbit(x)
return res
for i in range(1,n+1):
add(i,a[i])
for i in range(m):
op,l,r = map(int,input().split())
if op==1:add(l,r)
else:
print(quary(r)-quary(l-1))
试题二:【模板】树状数组2
【题目描述】
如题,已知一个数列,你需要进行下面两种操作:
-
将某区间每一个数加上 x;
-
求出某一个数的值。
【输入格式】
第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。
第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。
接下来 M 行每行包含 2 或 4个整数,表示一个操作,具体如下:
操作 1: 格式:1 x y k
含义:将区间[x,y] 内每个数加上 k;
操作 2: 格式:2 x
含义:输出第 x 个数的值。
【输出格式】
输出包含若干行整数,即为所有操作 2 的结果。
【输入样例】
python
5 5
1 5 4 2 3
1 2 4 2
2 3
1 1 5 -1
1 3 5 7
2 4
【输出样例】
python
6
10
【解题思路】
区间修点查,模板题
【Python程序代码】
python
n,m = map(int,input().split())
a = [0] + list(map(int,input().split()))
s = [0]*(len(a)+1)
def lowbit(x):
return x&-x
def add(i,x):
while i<=n:
s[i]+=x
i+=lowbit(i)
def quary(x):
res = 0
while x:
res += s[x]
x-=lowbit(x)
return res
for i in range(m):
b = list(map(int,input().split()))
if b[0]==1:
add( b[1],b[3] )
add(b[2]+1,-b[3])
else:
print( a[b[1]] + quary(b[1]) )
试题三:动态求连续区间和
【题目描述】
给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和。
【输入格式】
第一行包含两个整数 n 和 m,分别表示数的个数和操作次数。
第二行包含 n 个整数,表示完整数列。
接下来 m 行,每行包含三个整数 k,a,b(k=0,表示求子数列[a,b]的和;k=1,表示第 a 个数加 b)。
数列从 1 开始计数。
【输出格式】
输出若干行数字,表示 k=0 时,对应的子数列 [a,b]的连续和。
【数据范围】
1≤n≤100000,
1≤m≤100000,
1≤a≤b≤n,
数据保证在任何时候,数列中所有元素之和均在 int 范围内。
【输入样例】
python
10 5
1 2 3 4 5 6 7 8 9 10
1 1 5
0 1 3
0 4 8
1 7 5
0 4 8
【输出样例】
11
30
35
【解题思路】
点修区间查,模板题
【Python程序代码】
python
n,m = map(int,input().split())
a = [0] + list(map(int,input().split()))
s = [0]*(len(a)+10)
def lowbit(x):
return x&-x
def add(x,k):
while x<=n:
s[x]+=k
x+=lowbit(x)
def quary(x):
res = 0
while x:
res += s[x]
x -= lowbit(x)
return res
for i in range(1,n+1):add(i,a[i])
for i in range(m):
k,a,b = map(int,input().split())
if k==0:
print( quary(b)-quary(a-1) )
else:
add(a,b)
试题四: 一个简单的整数问题
【题目描述】
给定长度为 N 的数列 A,然后输入 M 行操作指令。
第一类指令形如 C l r d
,表示把数列中第 l∼r 个数都加 d。
第二类指令形如 Q x
,表示询问数列中第 x 个数的值。
对于每个询问,输出一个整数表示答案。
【输入格式】
第一行包含两个整数 N 和 M。
第二行包含 N 个整数 A[i]。
接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。
【输出格式】
对于每个询问,输出一个整数表示答案。
每个答案占一行。
【数据范围】
1≤N,M≤105
|d|≤10000,
|A[i]|≤109
【输入样例】
python
10 5
1 2 3 4 5 6 7 8 9 10
Q 4
Q 1
Q 2
C 1 6 3
Q 2
【输出样例】
python
4
1
2
5
【解题思路】
区间修点查,模板题
【Python程序代码】
python
n,m = map(int,input().split())
a = [0] + list(map(int,input().split()))
s = [0]*(len(a)+10)
def lowbit(x):
return x&-x
def add(x,k):
while x<=n:
s[x]+=k
x+=lowbit(x)
def quary(x):
res=0
while x:
res += s[x]
x-=lowbit(x)
return res
for i in range(m):
mp = input().split()
if mp[0] == "C":
l,r,d = int(mp[1]),int(mp[2]),int(mp[3])
add(l,d); add(r+1,-d)
else:
x = int(mp[1])
print(a[x] + quary(x))
试题五:一个简单的整数问题2
【题目描述】
给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:
C l r d
,表示把 A[l],A[l+1],...,A[r] 都加上 d。Q l r
,表示询问数列中第 l∼r 个数的和。
对于每个询问,输出一个整数表示答案。
【输入格式】
第一行两个整数 N,M。
第二行 N 个整数 A[i]。
接下来 M 行表示 M 条指令,每条指令的格式如题目描述所示。
【输出格式】
对于每个询问,输出一个整数表示答案。
每个答案占一行。
【数据范围】
1≤N,M≤105,
|d|≤10000,
|A[i]|≤109
【输入样例】
python
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
【输出样例】
python
4
55
9
15
【解题思路】
区间修区间查模板题
【Python程序代码】
python
n,m = map(int,input().split())
a = [0] + list(map(int,input().split()))
pre_a = [0]*(n+5)
s1,s2 = [0]*(n+5),[0]*(n+5)
def lowbit(x):
return x&-x
def add(s,x,k):
while x<=n:
s[x]+=k
x+=lowbit(x)
def quary(s,x):
res = 0
while x:
res += s[x]
x -= lowbit(x)
return res
for i in range(1,n+1):
pre_a[i]=pre_a[i-1] + a[i]
for i in range(m):
mp = input().split()
if mp[0]=='Q':
l,r = int(mp[1]),int(mp[2])
res = pre_a[r]-pre_a[l-1] + (quary(s1,r)*r-quary(s2,r)) - (quary(s1,l-1)*(l-1) - quary(s2,l-1))
print(res)
else:
l,r,k = int(mp[1]),int(mp[2]),int(mp[3])
add(s1,l,k); add(s1,r+1,-k)
add(s2,l,k*(l-1)); add(s2,r+1,-k*r)