问题分析
题意:
在一座高度为 H 的山上,每个高度 i 处生成了 a_i 个雪球。当雪球从海拔高度 i 滚到地面时,它的体积会膨胀 x^i 倍。也就是说,雪球的初始体积为 1,滚动距离 i 会使体积变成 1 * x^i。我们需要计算所有滚落到地面的雪球的总体积,并对结果取模 10^9 + 7。
你的任务是帮助计算所有雪球滚落到地面的总体积。
问题理解
-
输入:
H: 山的高度。x: 雪球体积膨胀的倍数。a: 一个长度为H的列表,表示每个高度i处的雪球数量。
-
输出:
- 所有雪球滚落到地面的总体积,对
10^9 + 7取模。
- 所有雪球滚落到地面的总体积,对
数据结构与算法选择
-
数据结构:
- 使用一个列表
a来存储每个高度的雪球数量。
- 使用一个列表
-
算法步骤:
- 对于每个高度
i,计算雪球滚落到地面的体积膨胀倍数x^i。 - 计算每个高度的雪球总体积,并累加到总和。
- 对总和取模
10^9 + 7。
- 对于每个高度
公式:
- 对于每个高度 ii,雪球膨胀后的体积为 ai⋅xia_i \cdot x^i。
- 总体积为 sum=∑i=0H−1ai⋅xi\text{sum} = \sum_{i=0}^{H-1} a_i \cdot x^i。
算法设计
-
快速幂:
- 由于直接计算 xix^i 会随着 ii 增大而变得很慢,因此使用快速幂法计算 )x^i mod (10^9 + 7),将复杂度从 O(i) 降到 O(logi)。
-
遍历计算总体积:
- 遍历每个高度 ii,对每一高度的雪球数量 a_i 和膨胀体积 x^i 求积。
- 将所有结果累加,并对 10^9 + 7 取模。
-
取模技巧:
- 每次计算x^i mod (10^9 + 7) 和 (a_i \cdot x^i) mod (10^9 + 7) 时都取模,防止数值溢出。
实现代码
def solution(H, x, a):
MOD = 10**9 + 7
# 快速幂计算 x^i % MOD
def fast_power(base, exp, mod):
result = 1
while exp > 0:
if exp % 2 == 1:
result = (result * base) % mod
base = (base * base) % mod
exp //= 2
return result
total_volume = 0
for i in range(H):
# 计算 x^i % MOD
power_x_i = fast_power(x, i, MOD)
# 计算当前高度贡献的体积,并累加到总和
total_volume = (total_volume + a[i] * power_x_i) % MOD
return total_volume
# 测试样例
print(solution(4, 5, [1, 3, 2, 4])) # 输出: 2830
print(solution(2, 5, [1, 2])) # 输出: 55
print(solution(3, 3, [2, 1, 1])) # 输出: 42
样例解释
样例 1:
输入:H = 4, x = 5, a = [1, 3, 2, 4]。
- 高度 0:1⋅50=11 \cdot 5^0 = 1
- 高度 1:3⋅51=153 \cdot 5^1 = 15
- 高度 2:2⋅52=502 \cdot 5^2 = 50
- 高度 3:4⋅53=5004 \cdot 5^3 = 500
- 总体积:1+15+50+500=28301 + 15 + 50 + 500 = 2830。
样例 2:
输入:H = 2, x = 5, a = [1, 2]。
- 高度 0:1⋅50=11 \cdot 5^0 = 1
- 高度 1:2⋅51=102 \cdot 5^1 = 10
- 总体积:1+10=551 + 10 = 55。
复杂度分析
-
时间复杂度:
- 快速幂计算
x^i的复杂度为O(logi),对每个高度进行累加的复杂度为O(HlogH)。
- 快速幂计算
-
空间复杂度:
- 快速幂只需要常数空间,整体空间复杂度为O(1)。