UVA 11582 Colossal Fibonacci Numbers!【数学】

大一刚开始接触ACM就买了《算法竞赛入门经典》这本书,当时只能看懂前几章,而且题目也没做,粗鄙地以为这本书不适合自己。等到现在快大三了再回过头来看,发现刘老师还是很棒的!

扯远了。。。

题意:问f[a^b]%n的值,f为斐波那契数。根据f[i]=f[i-1]+f[i-2]不难发现,当二元组(f[i],f[i-1])出现重复时,整个序列就开始重复了。如n=3,序列f[i]的前10项为

      0,1,1,2,0,2,2,1,0,1

f[9]和f[10]与前两项一样。

那么周期会在哪出现呢?从n项中取2项为C(n,2),即最多有n*(n-1)/2种组合,最多n^2,2<=n<=1000。实际上远小于n^2。

此时找到了周期长度m,答案为f[(a^b)%m],a^b用快速幂解决。

坑点,2^64得用usingned long long存,格式是%llu;注意n=1时要输出0。

代码:

#include<stdio.h>
#include<string.h>
typedef unsigned long long ll;
ll a,b;
int n,m,f[1111*1111];
int pow(ll a,ll b,int mod){
    int ans=1;
    while(b){
        if(b&1)    ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
int main(){
    
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%llu%llu%d",&a,&b,&n);
        f[0]=0,f[1]=1%n;
        for(int i=2;;i++){
            f[i]=f[i-2]+f[i-1];
            f[i]%=n;
            if(f[i]==f[1]&&f[i-1]==f[0]){
                m=i-1;
                break;
            }
        }
        int t=pow(a%m,b,m);
        printf("%d
",f[t]);
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/L-King/p/5757311.html