问题背景
我们称一个数字字符串是 好数字 当它满足(下标从 0 0 0 开始)偶数 下标处的数字为 偶数 且 奇数 下标处的数字为 质数 ( 2 , 3 , 5 (2, \ 3, \ 5 (2, 3, 5 或 7 ) 7) 7)。
- 比方说,“2582” 是好数字,因为偶数下标处的数字 ( 2 (2 (2 和 8 ) 8) 8) 是偶数且奇数下标处的数字 ( 5 (5 (5 和 2 ) 2) 2) 为质数。但 “3245” 不是好数字,因为 3 3 3 在偶数下标处但不是偶数。
给你一个整数
n
n
n,请你返回长度为
n
n
n 且为好数字的数字字符串 总数 。由于答案可能会很大,请你将它对
(
1
0
9
+
7
)
(10 ^ 9 + 7)
(109+7) 取余后返回 。
一个 数字字符串 是每一位都由
0
0
0 到
9
9
9 组成的字符串,且可能包含前导
0
0
0。
数据约束
- 1 ≤ n ≤ 1 0 15 1 \le n \le 10 ^ {15} 1≤n≤1015
解题过程
注意题目中的
n
n
n 表示数据的长度而不是范围,对长度可能达到
1
0
15
10 ^ {15}
1015 量级的数字,用暴力解是一定会超时的。
给定的数字中允许包含前导
0
0
0,实际上意味着每个整数奇数位上的数字和偶数位上的数字可能性是确定的,这是一个纯粹的排列组合问题。
考虑到数据范围特别大,结果需要用 快速幂 来计算。
具体实现
class Solution {
private static final int MOD = 1000000007;
public int countGoodNumbers(long n) {
return (int) (pow(5, (n + 1) >> 1) * pow(4, n >> 1) % MOD);
}
private long pow (long x, long n) {
long res = 1;
while (n > 0) {
if ((n & 1) > 0) {
res = res * x % MOD;
}
x = x * x % MOD;
n >>= 1;
}
return res;
}
}