UVA11582 Colossal Fibonacci

    xiaoxiao2021-04-18  68

    问题描述:

    这题花了我一天时间调,还是自己渣,很多细节都没注意。

    分析:

    因为要求的是 f(ab) mod n ,那么就可以设F(i)=f(i) mod n 。则f(ab) mod n=F(ab) 。 这里有一个关键的地方, f(i) mod n 会重复循环,为什么会这样呢?因为斐波那契数列的每一项都只和前两项有关。所以共有 n2 个可能,最后一定会出现循环节,也就是说余数最多 n 种,则最多 n2 项就会出现重复。

    这下就可以先建一个 F(i) 的表:因为根据斐波那契数列递推式:

    f(i)=f(i1)+f(i2) //式1

    根据式1和 (a+b) mod n=(a mod n+b mod n) mod n 得出

    f(i) mod n=(f(i1) mod n+f(i2) mod n) mod n //式2

    F(i)=f(i) mod n //式3

    则根据式2和式3得出

    F(i)=(f(i1) mod n+f(i2) mod n) mod n=(F(i1)+F(i2)) mod n

    F(i) 通过 F(i1) F(i2) 求和取模得出。关键是需要找到重复节的位置,并停止填表。 最后找到 ab 的位置,查表即可。

    代码如下:

    void Fibonacci_F() { F[0] = 0; F[1] = 1; for(int i=2; ; i++) { F[i] = (F[i-1] + F[i-2]) % n; if(F[i-1] == 0 && F[i] == 1) { k = i-1; break; } } return; }

    完整代码如下:

    #include<cstdio> #include<iostream> using namespace std; typedef unsigned long long LL; const int maxn = 10000000+10; int F[maxn]; LL a,b; int n,k; /*建表*/ void Fibonacci_F() { F[0] = 0; F[1] = 1; for(int i=2; ; i++) { F[i] = (F[i-1] + F[i-2]) % n; if(F[i-1] == 0 && F[i] == 1) { k = i-1; break; } } return; } /*幂求模*/ int pow_mod(LL a, LL b, int n) { if(b == 0) return 1; int x = pow_mod(a, b/2, n); x = x * x % n; if(b%2 == 1) x = x * a % n; return x; } int main() { int T; scanf("%d",&T); while(T--) { cin>>a>>b>>n; if(a == 0 || n == 1) { cout<<0<<endl;//关键。 } else{ Fibonacci(); printf("%d\n",F[pow_mod(a%k,b,k)]); } } return 0; }

    有一个细节很重要:

    if(a == 0 || n == 1) { cout<<0<<endl;//关键。 }

    就是因为少了这个,我一直runtime error,所以细节决定成败。

    转载请注明原文地址: https://ju.6miu.com/read-675204.html

    最新回复(0)