Colossal Fibonacci Numbers!

Posted ac-ac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Colossal Fibonacci Numbers!相关的知识,希望对你有一定的参考价值。

Colossal Fibonacci Numbers!

  1. 链接

  2. 题意

    输入两个非负整数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)。

  3. 分析

    所有计算都是对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)等于其中的哪一项即可。

  4. 代码实现

    #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;
    } 
  5. 总结

    取模的时候,特别注意一下1和0这种情况。

以上是关于Colossal Fibonacci Numbers!的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 11582 Colossal Fibonacci Numbers!循环节

Colossal Fibonacci Numbers!

Colossal Fibonacci Numbers! UVA - 11582

uva11582 Colossal Fibonacci Numbers!

UVA11582 Colossal Fibonacci Numbers!

UVa 11582 - Colossal Fibonacci Numbers!(数论)