Colossal Fibonacci Numbers!
Posted ac-ac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Colossal Fibonacci Numbers!相关的知识,希望对你有一定的参考价值。
Colossal Fibonacci Numbers!
题意
输入两个非负整数a,b和正整数n(0<=a,b<2^64,1<=n<=1000),你的任务是计算f(a^b)除以n的余数。其中f[0] =0,f[1] = 1,且对于所有的非负整数i,f(i+2) = f(i+1) +f(i)。
分析
所有计算都是对n取模的,不妨设F[i] = f[i]%n。不难发现,当二元组(f[i],f[i+1])出现重复时,整个序列就开始重复。为什么呢?是由递推序列的性质决定的,f(i+2) = f(i+1) +f(i)。例如,n=3,序列F[i]的前10项为1,1,2,0,2,2,1,0,1,1,第9,10项和前两项完全一样。根据递推公式,第11项会等于第3项,第12项等于第4项......多久会出现重复呢?因为余数最多有n种,所以最多n^2项就会出现重复。设周期为M,则只需计算出F[0]~F[n^2],然后计算出F(a^b)等于其中的哪一项即可。
代码实现
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; //此题会爆long long const int maxn = 1e6+5; int f[maxn]; ll ksm(ll a, ll b,int mod){ ll ans = 1; while(b){ if(b&1) ans = ans*a%mod; a = a*a%mod; b = b>>1; } return ans%mod; } int main(void) { int t; cin >> t; while(t--) { ll a,b; int n; cin >> a >> b >> n; if(a==0||n==1){ cout<<0<<endl; continue; } int T = 0; f[0] = 0; f[1] = 1; for(int i = 2; i <= n*n; i++){ f[i] = (f[i-1]+f[i-2])%n; if(f[i]==f[1]&&f[i-1]==f[0]){ T = i-1; break; } } int k = ksm(a%T,b,T); cout<<f[k]<<endl; } return 0; }
总结
取模的时候,特别注意一下1和0这种情况。
以上是关于Colossal Fibonacci Numbers!的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 11582 Colossal Fibonacci Numbers!循环节
Colossal Fibonacci Numbers! UVA - 11582
uva11582 Colossal Fibonacci Numbers!