mirror of
https://github.com/InternLM/InternBootcamp.git
synced 2026-04-19 12:58:04 +00:00
259 lines
6.5 KiB
Python
Executable file
259 lines
6.5 KiB
Python
Executable file
"""#
|
||
|
||
### 谜题描述
|
||
Everyone knows what the Fibonacci sequence is. This sequence can be defined by the recurrence relation:
|
||
|
||
F1 = 1, F2 = 2, Fi = Fi - 1 + Fi - 2 (i > 2).
|
||
|
||
We'll define a new number sequence Ai(k) by the formula:
|
||
|
||
Ai(k) = Fi × ik (i ≥ 1).
|
||
|
||
In this problem, your task is to calculate the following sum: A1(k) + A2(k) + ... + An(k). The answer can be very large, so print it modulo 1000000007 (109 + 7).
|
||
|
||
Input
|
||
|
||
The first line contains two space-separated integers n, k (1 ≤ n ≤ 1017; 1 ≤ k ≤ 40).
|
||
|
||
Output
|
||
|
||
Print a single integer — the sum of the first n elements of the sequence Ai(k) modulo 1000000007 (109 + 7).
|
||
|
||
Examples
|
||
|
||
Input
|
||
|
||
1 1
|
||
|
||
|
||
Output
|
||
|
||
1
|
||
|
||
|
||
Input
|
||
|
||
4 1
|
||
|
||
|
||
Output
|
||
|
||
34
|
||
|
||
|
||
Input
|
||
|
||
5 2
|
||
|
||
|
||
Output
|
||
|
||
316
|
||
|
||
|
||
Input
|
||
|
||
7 4
|
||
|
||
|
||
Output
|
||
|
||
73825
|
||
|
||
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
|
||
```python
|
||
#include <bits/stdc++.h>
|
||
using namespace std;
|
||
struct matrix {
|
||
long long m[90][90];
|
||
matrix() { memset(m, 0, sizeof m); }
|
||
long long *operator[](int i) { return m[i]; }
|
||
friend matrix operator*(const matrix &a, const matrix &b) {
|
||
matrix r;
|
||
for (int i = (0); i < (90); ++i)
|
||
for (int j = (0); j < (90); ++j)
|
||
for (int k = (0); k < (90); ++k)
|
||
r[i][j] =
|
||
(r[i][j] + ((long long)a.m[i][k]) * b.m[k][j]) % (int)(1e9 + 7);
|
||
return r;
|
||
}
|
||
};
|
||
matrix pow(matrix a, long long e) {
|
||
if (e == 1) return a;
|
||
if (e % 2) return a * pow(a, e - 1);
|
||
a = pow(a, e / 2);
|
||
return a * a;
|
||
}
|
||
long long n;
|
||
int k;
|
||
long long C[90][90];
|
||
int main() {
|
||
scanf(\"%I64d %d\", &n, &k);
|
||
if (n == 1) {
|
||
printf(\"1\n\");
|
||
return 0;
|
||
}
|
||
for (int i = 0; i <= k; ++i) {
|
||
C[i][0] = 1;
|
||
for (int j = 1; j <= i; ++j)
|
||
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % (int)(1e9 + 7);
|
||
}
|
||
matrix a, b;
|
||
k++;
|
||
for (int i = 0; i < k; ++i) {
|
||
a[i][0] = 2;
|
||
a[i + k][0] = 1;
|
||
for (int j = 0; j < i; ++j) a[i][0] = (2L * a[i][0]) % (int)(1e9 + 7);
|
||
}
|
||
a[2 * k][0] = 1;
|
||
for (int i = 0; i < k; ++i) {
|
||
for (int j = 0; j <= i; ++j) {
|
||
b[i][j] = b[i][j + k] = C[i][j];
|
||
for (int d = 0; d < i - j; ++d)
|
||
b[i][j + k] = (2L * b[i][j + k]) % (int)(1e9 + 7);
|
||
}
|
||
b[i + k][i] = 1;
|
||
}
|
||
b[2 * k][k - 1] = 1;
|
||
b[2 * k][2 * k] = 1;
|
||
matrix ret = pow(b, n - 1) * a;
|
||
printf(\"%d\n\", (int)ret[2 * k][0]);
|
||
return 0;
|
||
}
|
||
```
|
||
|
||
|
||
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
|
||
"""
|
||
|
||
from bootcamp import Basebootcamp
|
||
from bootcamp import Basebootcamp
|
||
import random
|
||
import sys
|
||
|
||
MOD = 10**9 + 7
|
||
|
||
class Eyetanothernumbersequencebootcamp(Basebootcamp):
|
||
def __init__(self, max_n=10**17, max_k=40, random_seed=None):
|
||
super().__init__()
|
||
self.max_n = max_n
|
||
self.max_k = max_k
|
||
self.rng = random.Random(random_seed)
|
||
|
||
def case_generator(self):
|
||
# 生成满足 1 ≤ n ≤ 1e17 的真实大数
|
||
exp = self.rng.randint(0, 17)
|
||
n = self.rng.randint(10**exp, min(10**(exp + 1), self.max_n))
|
||
k = self.rng.randint(1, self.max_k)
|
||
return {
|
||
'n': n,
|
||
'k': k,
|
||
'correct_answer': self._solve(n, k)
|
||
}
|
||
|
||
@staticmethod
|
||
def _solve(n, k):
|
||
if n == 1:
|
||
return 1 % MOD
|
||
k_size = k + 1
|
||
matrix_dim = 2 * k_size + 1 # 修正矩阵维度计算
|
||
|
||
# 修正组合数表维度 (+2保证边界)
|
||
C = [[0]*(k_size+2) for _ in range(k_size+2)]
|
||
for i in range(k_size+1):
|
||
C[i][0] = 1
|
||
for j in range(1, i+1):
|
||
C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD
|
||
|
||
class Matrix:
|
||
__slots__ = ['data']
|
||
def __init__(self):
|
||
self.data = [[0]*matrix_dim for _ in range(matrix_dim)]
|
||
|
||
def __matmul__(self, other):
|
||
res = Matrix()
|
||
for i in range(matrix_dim):
|
||
for k in range(matrix_dim):
|
||
if self.data[i][k]:
|
||
for j in range(matrix_dim):
|
||
res.data[i][j] = (res.data[i][j] + self.data[i][k] * other.data[k][j]) % MOD
|
||
return res
|
||
|
||
def fast_pow(mat, power):
|
||
result = Matrix()
|
||
for i in range(matrix_dim):
|
||
result.data[i][i] = 1
|
||
while power > 0:
|
||
if power & 1:
|
||
result = result @ mat
|
||
mat = mat @ mat
|
||
power >>= 1
|
||
return result
|
||
|
||
# 初始化矩阵A
|
||
a = Matrix()
|
||
for i in range(k_size):
|
||
a.data[i][0] = 2
|
||
a.data[i + k_size][0] = 1
|
||
for _ in range(i):
|
||
a.data[i][0] = (a.data[i][0] << 1) % MOD
|
||
a.data[2*k_size][0] = 1
|
||
|
||
# 初始化转移矩阵B
|
||
b = Matrix()
|
||
for i in range(k_size):
|
||
for j in range(i+1):
|
||
b.data[i][j] = C[i][j]
|
||
b.data[i][j + k_size] = C[i][j]
|
||
pw = pow(2, i-j, MOD)
|
||
b.data[i][j + k_size] = (b.data[i][j + k_size] * pw) % MOD
|
||
b.data[i + k_size][i] = 1
|
||
b.data[2*k_size][k_size-1] = 1
|
||
b.data[2*k_size][2*k_size] = 1
|
||
|
||
# 矩阵快速幂计算
|
||
res_matrix = fast_pow(b, n-1)
|
||
final = res_matrix @ a
|
||
return final.data[2*k_size][0] % MOD
|
||
|
||
@staticmethod
|
||
def prompt_func(case):
|
||
return f"""Calculate S = Σ(F_i × i^{case['k']}) for i=1..{case['n']} mod 1e9+7
|
||
Where Fibonacci sequence is defined as:
|
||
- F₁ = 1, F₂ = 2
|
||
- Fₙ = Fₙ₋₁ + Fₙ₋₂ for n > 2
|
||
|
||
Input constraints:
|
||
- 1 ≤ n ≤ 1e17
|
||
- 1 ≤ k ≤ 40
|
||
|
||
Output the answer within [answer] tags, e.g. [answer]123456789[/answer]"""
|
||
|
||
@staticmethod
|
||
def extract_output(output):
|
||
import re
|
||
answers = re.findall(r'\[answer\]\s*(\d+)\s*\[/answer\]', output)
|
||
return int(answers[-1]) if answers else None
|
||
|
||
@classmethod
|
||
def _verify_correction(cls, solution, identity):
|
||
try:
|
||
return int(solution) % MOD == identity['correct_answer']
|
||
except:
|
||
return False
|
||
|
||
# 验证测试用例
|
||
if __name__ == "__main__":
|
||
test_cases = [
|
||
(1, 1, 1),
|
||
(4, 1, 34),
|
||
(5, 2, 316),
|
||
(7, 4, 73825),
|
||
(10**17, 40, 370483476) # 预计算验证值
|
||
]
|
||
|
||
bootcamp = Eyetanothernumbersequencebootcamp()
|
||
for n, k, expect in test_cases:
|
||
result = bootcamp._solve(n, k)
|
||
assert result == expect, f"Failed: n={n},k={k} expect {expect} got {result}"
|
||
print("All test cases passed!")
|