小R的雪球滚落计算
问题描述
在一座高度为 H 的山上,每个高度 i 处生成了 a_i 个雪球。当雪球从海拔高度 i 滚到地面时,它的体积会膨胀 x^i 倍。也就是说,雪球的初始体积为 1,滚动距离 i 会使体积变成 1 * x^i。我们需要计算所有滚落到地面的雪球的总体积,并对结果取模 10^9 + 7。
你的任务是帮助计算所有雪球滚落到地面的总体积。
测试样例
样例1:
输入:
H = 4, x = 5, a = [1, 3, 2, 4]
输出:2830
样例2:
输入:
H = 2, x = 5, a = [1, 2]
输出:55
样例3:
输入:
H = 3, x = 3, a = [2, 1, 1]
输出:42
思路
-
理解体积膨胀公式:
- 初始体积为 1。
- 当雪球从海拔高度 ii 滚到地面时,体积膨胀 xixi 倍。
- 因此,海拔高度 ii 处 aiai 个雪球滚落到地面的体积为 ai×xiai×xi。
-
总体积计算:
- 我们需要计算所有海拔高度处雪球滚落到地面的总体积。
- 公式为:总体积=∑i=0H−1(ai×xi)总体积=∑i=0H−1(ai×xi)。
-
模运算:
- 由于结果可能非常大,我们需要对结果取模 109+7109+7。
- 模运算的性质允许我们在每一步计算中取模,以防止数值溢出。
-
实现细节:
- 计算 xixi 时,可以使用快速幂算法来提高效率。
- 在每次计算 ai×xiai×xi 后,立即取模 109+7109+7。
具体步骤
-
初始化总体积为 0。
-
遍历每个海拔高度 ii:
- 计算 ai×xiai×xi。
- 对结果取模 109+7109+7。
- 将结果累加到总体积中,并对总体积取模 109+7109+7。
-
输出总体积。
示例
以样例1为例:
-
输入:H=4H=4, x=5x=5, a=[1,3,2,4]a=[1,3,2,4]
-
计算:
- 海拔高度 0:1×50=11×50=1
- 海拔高度 1:3×51=153×51=15
- 海拔高度 2:2×52=502×52=50
- 海拔高度 3:4×53=5004×53=500
-
总体积:1+15+50+500=5661+15+50+500=566,取模 109+7109+7 后仍为 566。
完整代码
public class Main {
private static final int MOD = 1000000007;
public static int solution(int H, int x, int[] a) {
long result = 0;
for (int i = 0; i < H; i++) {
// 计算单个雪球从高度 i 滚到地面时的体积,即 x^i
long volume = powerMod(x, i + 1, MOD);
// 将该高度的所有雪球的体积加起来
result += (long)a[i] * volume % MOD;
result %= MOD; //确保结果不会溢出
}
return (int)result;
}
// 快速幂算法,用于计算 (base^exp) % mod
private static long powerMod(long base, long exp, long mod) {
long result = 1;
while (exp > 0) {
if ((exp & 1) == 1) { // 如果 exp 是奇数
result = result * base % mod;
}
base = base * base % mod;
exp >>= 1; // 相当于 exp = exp / 2
}
return result;
}
public static void main(String[] args) {
System.out.println(solution(4, 5, new int[]{1, 3, 2, 4}) == 2830);
System.out.println(solution(2, 5, new int[]{1, 2}) == 55);
System.out.println(solution(3, 3, new int[]{2, 1, 1}) == 42);
}
}