Colossal Fibonacci Numbers(巨大的斐波那契数)UVA 11582

 评测地址:http://acm.hust.edu.cn/vjudge/problem/41990

 1 The i'th Fibonacci number f (i) is recursively de ned in the following way:
 2 
 3 f (0) = 0 and f (1) = 1
 4 
 5 f (i + 2) = f (i + 1) + f (i) for every i 0
 6 
 7 Your task is to compute some values of this sequence.
 8 
 9 Input
10 
11 Input begins with an integer t
12 10; 000, the number of test cases.
13 
14 Each test case consists of three in-tegers a, b, n where 0 a; b < 264 (a and b will not both be zero) and 1 n 1000.
15 
16 Output
17 
18 For each test case, output a single line containing the remainder of f (ab) upon division by n.
19 
20 Sample Input
21 
22 3
23 1 1 2
24 2 3 1000
25 18446744073709551615 18446744073709551615 1000
26 
27 Sample Output
28 
29 1
30 21
31 250
题目文本

题目大意:

输入两个非负整数a,b和正整数n(0<=a,b<2^64,1<=n<=1000),你的任务是计算f(a^b)除以n的余数。其中f(0)=f(1)=1,且对于所有非负整数i,f(i+2)=f(i+1)+f(i)。

解题思路:

这么大的数字,直接算是不现实的。

此时我们会想,要是f(i)% n能出现循环多好啊。

我们取F(i)=f(i) % n。若(F(i-1),F(i))出现重复,则整个序列将开始重复。 比如n=3时 1,1,2,0,2,2,1,0,1,1,2,0,2,2… 因为余数最多有n种可能,所以最多到第n^2项,就会出现重复,开始循环。 所以我们先花至多O(n^2)的时间处理一下找到循环节,再判断一下F(a^b)具体等于哪一项即可。

AC代码:

#include<cstdio>
#include<iostream>
#define ll unsigned long long 
using namespace std;
const int N=1e6+100;
int T,n,mod,f[N]={0,1,1};
ll a,b;
int kpow(ll a,ll p){
    int ans=1;
    for(;p;p>>=1,a=(a*a)%mod) if(p&1) ans=(ans*a)%mod;
    return ans;
}
int main(){
    cin>>T;
    while(T--){
        cin>>a>>b>>n;
        if(n==1||!a){printf("0\n");continue;}
        for(int i=3;i<=n*n+10;i++){
            f[i]=(f[i-1]+f[i-2])%n;
            if(f[i]==f[2]&&f[i-1]==f[1]){mod=i-2;break;}
        }
        printf("%d\n",f[kpow(a%mod,b)]);
    }
    return 0;
}

 

 

posted @ 2016-07-26 15:44  神犇(shenben)  阅读(497)  评论(1编辑  收藏  举报