一本通 1189:Pell数列

时间限制: 1000 ms 内存限制: 65536 KB
提交数: 20303 通过数: 10334

【题目描述】

Pell数列a1,a2,a3,...a1,a2,a3,...的定义是这样的,a1=1,a2=2,...,an=2an−1+an−2(n>2)a1=1,a2=2,...,an=2an−1+an−2(n>2)。给出一个正整数k,要求Pell数列的第k项模上32767是多少。

【输入】

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数k (1≤k<1000000)。

【输出】

n行,每行输出对应一个输入。输出应是一个非负整数。

【输入样例】

2 1 8

【输出样例】

1 408

【关于求模数学公式】

运算规则
模运算与基本四则运算有些相似,但是除法例外。其规则如下:

(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
a ^ b % p = ((a % p)^b) % p (4) 

结合律:

((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
((ab) % p * c)% p = (a * (bc) % p) % p (6) 

交换律:

(a + b) % p = (b+a) % p (7)
(a * b) % p = (b * a) % p (8)

分配律:

(a+b) % p = ( a % p + b % p ) % p (9)
((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (10) 

重要定理

若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);(11)
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);(12)
若a≡b (% p),c≡d (% p),则 :
(a + c) ≡ (b + d) (%p),
(a - c) ≡ (b - d) (%p), 
(a * c) ≡ (b * d) (%p); (13)
————————————————
版权声明:本文为CSDN博主「霍雨浩——舞麟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/b_o_n_z_t_f/article/details/105014811

【网上的答案】

// https://blog.csdn.net/u011815404/article/details/80085032
#include<iostream>
using namespace std;
int a[1000100];
int main()
{
    int n,k,i;
    a[1]=1;
    a[2]=2;
    for(i=3;i<=1000000;i++)
        a[i]=(2*a[i-1]+a[i-2])%32767;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>k;
        cout<<a[k]<<endl;
    }
    return 0;
}

【我的答案】

# include <bits/stdc++.h>

using namespace std;

int main (){
	int n;
	cin >> n;
	int num;
	
	int a, b, c;
	
	const int p = 32767;
	while(n--){
		scanf("%d", &num);
		a = 1;
		b = 2;
		c = 5;
		
		if(num == 1){
			printf("1\n");
		}
		else if (num == 2){
			printf("2\n");	
		}
		else if (num == 3){
			printf("5\n");	
		}
		else{
			num -= 3;
			while(num--){
				a = b;
				b = c;
				//c = ((a%p) + (2*(b%p))%p)%p;
				c = (a + 2*b)%p;
			}
			printf("%d\n", c);
		}	
	} 
	
	return 0;
} 
//2021年10月6日18:20:35