UVA11582 巨大的斐波那契数! Colossal Fibonacci Numbers!

https://www.luogu.com.cn/problem/UVA11582
sol:
因为\(a\)与b的范围是ULL级别的(ULL < 2^64, LL < 2^63),所以肯定答案会循环。
\((F[i], F[i +1])\)第一次重复时,那么 i 就是循环周期。二元组最多有p^2种不同的取值(抽屉原理),但是实际上只有大约i取到6 * p的时候就会开始循环。
用f[mod][i]表示再 % mod 的前提下,F[i]的值为多少。如果f[mod][i] == 1&& f[mod][i - 1] == 0,那么循环节就是i - 1。
trick:计算快速幂a^b % p时,可以先将a % p,再求快速幂。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

typedef unsigned long long LL;
const int N = 1e3 + 100, B = 1000;
int f[N][N * 6], prid[N];

int qmi(LL a, LL b, int p) {
	LL res = 1 % p;
	for( ; b; b >>= 1) {
		if( b & 1)
		    res = res * a % p;
		a = a * a % p;
	}
	return (int)res;
}

int solve(LL a, LL b, int p) {
	if(p == 1)	return 0;
	return f[p][qmi(a % prid[p], b, prid[p])];
}

int main() {
	int T, p;
	LL a, b;
	for(int mod = 2; mod <= 1000; mod ++) {
		f[mod][0] = 0, f[mod][1] = 1;
		for(int i = 2; ; i ++) {
			f[mod][i] = (f[mod][i - 1] + f[mod][i - 2]) % mod;
			if( f[mod][i - 1] == 0 && f[mod][i] == 1) {
				prid[mod] = i - 1;
				break;
			}
		}
	}
	scanf("%d", &T);	
	while( T --) {
		cin >> a >> b >> p;
		printf("%d\n", solve(a, b, p)); 
	}
	return 0;
} 
posted @ 2020-09-03 20:47  王雨阳  阅读(194)  评论(0)    收藏  举报