利用同余封闭性先递推打表到最大 k,再 O(1) 回答每组询问。
OJ: roj
题目 ID: 1202
难度:入门
标签:递推打表同余
创建: 2026-09-29 23:15
更新: 2026-10-05 05:27
题目描述
Pell 数列定义为
思路
利用同余封闭性先递推打表到所有询问的最大
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 23:15
# update_at: 2026-09-29 23:15
import sys
MOD = 32767 # 题面给定的模数
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
T = next(data)
ks = [next(data) for _ in range(T)] # 所有询问的 k,先读入再一起回答
# Pell 数列前 max(ks) 项整体取模:递推只涉及加法和乘法,模运算下保持一致
limit = max(ks)
pell = [0] * (limit + 1)
pell[1] = 1 % MOD
if limit >= 2:
pell[2] = 2 % MOD
for i in range(3, limit + 1):
pell[i] = (2 * pell[i - 1] + pell[i - 2]) % MOD
print('\n'.join(str(pell[k]) for k in ks))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-05 05:27
* update_at: 2026-10-05 05:27
*/
#include <cstdio>
typedef long long ll;
const int MAXN = 1000005; // k < 1000000,留足余量
const int MOD = 32767;
int p[MAXN]; // p[i] 表示 Pell 数列第 i 项模 32767 的值,值域 [0, 32766],用 int 即可
int q[MAXN]; // 所有询问的 k
int main() {
int n;
scanf("%d", &n);
int L = 0; // 询问中最大的 k
for (int i = 0; i < n; i++) {
scanf("%d", &q[i]);
if (q[i] > L) L = q[i];
}
p[1] = 1;
p[2] = 2;
for (int i = 3; i <= L; i++) {
p[i] = (2 * p[i - 1] + p[i - 2]) % MOD;
}
for (int i = 0; i < n; i++) {
printf("%d\n", p[q[i]]);
}
return 0;
}