码迷,mamicode.com
首页 > 其他好文 > 详细

Colossal Fibonacci Numbers!

时间:2020-02-16 14:30:00      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:tin   amp   元组   turn   就会   mod   注意   loss   int   

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!

标签:tin   amp   元组   turn   就会   mod   注意   loss   int   

原文地址:https://www.cnblogs.com/AC-AC/p/12316663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!