1. 程式人生 > >UVa 11582 Colossal Fibonacci Numbers! 【大數冪取模】

UVa 11582 Colossal Fibonacci Numbers! 【大數冪取模】

term sign fontsize name fib sep iss style watermark

題目鏈接:Uva 11582 [vjudge]

技術分享

題意

輸入兩個非負整數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)。

分析

全部的計算都是對n取模。設F(i) =f(i)mod n, 非常easy發現,F(x)是具有周期性的,由於對N取模的值最多也就N個,當二元組(F(i-1),F(i))反復的時候。整個序列也就反復了。周期i – 1啊,自己能夠找組小的數據研究研究,就能夠發現這個規律了。

周期最大會有多大呢?因為余數最多也就N個。那麽最多N^2就會反復,全然能夠才時限內攻克了。

剩下的知識就是針對高速冪取模了,這個在我另外一篇博客《超級高速冪【費馬小定理】+【高速冪取模】》裏面有比較具體的介紹。

參考代碼

/****************************>>>>HEADFILES<<<<****************************/
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
/****************************>>>>>DEFINE<<<<<*****************************/
#define fst             first
#define snd             second
#define root            1,N,1
#define lson            l,mid,rt<<1
#define rson            mid+1,r,rt<<1|1
#define PB(a)           push_back(a)
#define MP(a,b)         make_pair(a,b)
#define CASE(T)         for(scanf("%d",&T);T--;)
#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//typedef unsigned __int64 ull;
typedef unsigned long long ull;
typedef pair<int, int>   pii;
const int INF = 0x3f3f3f3f;
const int maxn = 1000 + 5;
const int maxm = 20000 + 5;
/****************************>>>>SEPARATOR<<<<****************************/
int T, N;
ull a, b;
int ans[maxn*maxn];
int Fibo(const int& MOD)
{
    int ret;
    ans[0] = 0, ans[1] = 1 % MOD;
    int i = 2;
    while(1)
    {
        ans[i] = (ans[i - 1] + ans[i - 2]) % MOD;
        if(ans[i - 1] == 0 && ans[i] == 1 % MOD) break;
        i++;
    }
    return i - 1;
}
int pow_mod(ull x, ull y, int MOD)
{
    ull ret = 1;
    while(y)
    {
        if(y & 1) ret = (ret * x) % MOD;
        x = (x * x) % MOD;
        y >>= 1;
    }
    return (int)ret;
}
int main()
{
//    FIN;
    CASE(T)
    {
        scanf("%llu %llu %d",&a,&b,&N);
        if(a == 0 || N == 1)
        {
            printf("0\n");
            continue;
        }
        int Cyc = Fibo(N);
        int pos = pow_mod(a % Cyc, b, Cyc);
        printf("%d\n",ans[pos]);
    }
    return 0;
}


UVa 11582 Colossal Fibonacci Numbers! 【大數冪取模】