[每日N题] 4.2 Colossal Fibonacci Numbers! UVA - 11582 [数论]

题目: Colossal Fibonacci Numbers! UVA - 11582

思路:

所有计算都是对n取模的,不妨设F(i)=f(i) mod n。不难发现,当二元组(F(i), F(i+1))出现重复时,整个序列就开始重复。例如,n=3,序列F(i)的前10项为1,1,2,0,2,2,1,0,1,1,第9、10项和前两项完全一样。根据递推公式,第11项会等于第3项,第12项等于第4项……多久会出现重复呢?因为余数最多n种,所以最多n2项就会出现重复。设周期为M,则只需计算出F(0)~F(n2),然后算出F(ab)等于其中的哪一项即可。
——《算法竞赛入门 第二版》

我的代码:

#include<iostream>

#define ULL unsigned long long // 数据类型为 unsigned long long
using namespace std;

const int MAXN2 = 1000000;

int fab[MAXN2+100], N;
ULL A, B;

ULL powerMod (ULL a, ULL n, ULL m) {
	if (n == 0) return 1;
	ULL x = powerMod(a, n/2, m);
	ULL ans = (x*x)%m;
	if (n%2 == 1) {
		ans = ans*a%m;
	} 
	return ans;
}

int main () {
	int T;
	fab[1] = fab[2] = 1;
	cin >> T;
	while (T--) {
		cin >> A >> B >> N;
		if (N == 1) {
			cout << 0 << endl; // 如果n=1结果就一定为0
			continue;
		}
		ULL cycLen;
		for (int i = 3; i <= MAXN2; i++) {
			fab[i] = (fab[i-1] + fab[i-2])%N;
			if (fab[i] == 1 && fab[i-1] == 1) {
				cycLen = i-2; // 此时开始循环
				break;
			}
		}
		ULL index = powerMod(A%cycLen, B, cycLen);
		cout << fab[index] << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/AdamAndTina/article/details/88978550