【题目描述】
Pell数列a1,a2,a3,...的定义是这样的,a1=1,a2=2,...,an=2an−1+an−2(n>2)。
给出一个正整数 k,要求Pell数列的第 k项模上 3276732767 是多少。
【输入】
第1行是测试数据的组数 n,后面跟着 n行输入。每组测试数据占 11 行,包括一个正整数k(1≤k<1000000)。
【输出】
n行,每行输出对应一个输入。输出应是一个非负整数。
【输入样例】
2
1
8
【输出样例】
1
408
【解题思路】
Pell数列的定义
Pell数列是通过以下递归关系定义的:
a1 = 1
a2 = 2
- 对于所有
n > 2
,an = 2*an-1 + an-2
这意味着,每一项都是前一项的两倍加上前前一项。
解题思路
-
初始化:由于第一个和第二个数是固定的,即
a1 = 1
和a2 = 2
,我们可以从第三个数开始计算。 -
循环计算:使用一个循环,从
3
到k
,使用Pell数列的定义来计算每一项。由于每次计算只需要前两项,我们可以仅保留最近的两项来减少内存使用。 -
模运算的性质:由于最终结果需要对
32767
取模,我们可以利用模运算的性质((a + b) % c = ((a % c) + (b % c)) % c
)在每步计算中应用模运算,以避免整数溢出并减少计算时间。 -
输出结果:计算出第
k
项后,输出其对32767
取模的结果。
【实现代码】
#include <iostream>
using namespace std;
int pell(int k) {
if (k == 1) return 1;
if (k == 2) return 2;
int a = 1, b = 2, c;
for (int i = 3; i <= k; ++i) {
c = (2 * b + a) % 32767; // 计算当前项并取模
a = b; // 更新前两项
b = c;
}
return c;
}
int main() {
int n;
cin >> n; // 读取测试数据组数
while (n--) {
int k;
cin >> k; // 读取每组测试数据
cout << pell(k) << endl; // 输出每组数据的结果
}
return 0;
}