Uva11582

最近各种破事忙死了

终于开始做题了

紫薯第10章第一题,come on

设g(i)=f(i) mod n,当二元组(g(i)、g(i+1))出现重复时,整个序列就开始重复(这一话怎么也不懂,请大神解释)

余数最多n种,所以最多n^2项就会出现重复。设周期为m,只需计算出g(0)~g(n^2)项,然后计算g(a^b)等于其中的哪一项即可

但是,n<=1000,那么n方的规模会达到10^6,显然f(n^2)有些庞大

我们可以利用(a+b)mod n=((a mod n)+(b mod n))mod n 优化

那么g(i+2)=g(i+1)+g(i)=(f(i+1)mod n + f(i)mod n )mod n=(g(i+1)+g(i))mod n

 

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int T;
int n;
unsigned long long a,b;
int g[2005001];
int PowerMod(unsigned long long a, unsigned long long b, int c)
{
    int ans = 1;
    a = a % c;
    while(b>0) {
        if(b % 2 == 1)
        ans = (ans * a) % c;
        b = b/2;
        a = (a * a) % c;
    }
    return ans;
}
int main()
{
    cin>>T;
    while (T--){
        cin>>a>>b>>n;
        if(n==1)
        {
            puts("0"); continue;
        }
        int m=1;
        g[1]=1;g[2]=1;
        int i=3;
        while (1){
            g[i]=(g[i-1]+g[i-2])%n;
            if (g[1]==g[i-1]&&g[2]==g[i]) break;
            i++;
        }
        m=i-2;
        int s=PowerMod(a,b,m);
        cout<<g[s]<<endl;
    }
}

注意n==0的时候,可能会发生re

posted @ 2015-05-25 20:08  ACBingo  阅读(405)  评论(0编辑  收藏  举报