hdu 5451(矩阵 +Fibonacci )

题意:求 [(5 + 2*sqrt(6))^(1 + 2^x)]  % M

基于hdu2256可以求(5 + 2*sqrt(6))^ n

但是n特别大,我们可以找矩阵的循环节

两种可能 1.mod-1      2. (mod+1) * (mod-1)    /*(具体ACdreamers的广义裴波那切找循环节)

在知道2256时,自己做了一遍,但是到时想到的是费马小定理(gg)

p.s  广义Fibonacci数和循环节方面还是不明白,找机会看看


#include <iostream>
#include <cstdio>
using namespace std;
int mod;
typedef long long ll;
struct Matri
{
    int a[2][2];
};
Matri Mat;

Matri Mul(const Matri &A,const Matri &B)
{
    Matri c;
    for(int i=0; i<2; i++)
    {
        for(int j=0; j<2; j++)
        {
            c.a[i][j]=0;
            for(int k=0; k<2; k++)
            {
                c.a[i][j]+= (A.a[i][k]*B.a[k][j])%mod;
                c.a[i][j]%=mod;
            }
        }
    }
    return c;
}

Matri Pow(int n)
{
    if(n==1)
        return Mat;
    else if(n&1)
    {
        return Mul(Mat,Pow(n-1));
    }
    else
    {
        Matri temp=Pow(n>>1);
        return Mul(temp,temp);
    }
}

int PowerMod(ll a, int b, ll c)
{

    ll ans = 1;
    ll k = a % c;
    while(b>0)
    {
        if(b % 2 == 1)
            ans = (ans * k) % c;
        b = b/2;
        k = (k * k) % c;
    }
    return ans;

}
int main()
{
    int T;
    scanf("%d",&T);
    int cas = 1;
    while(T--)
    {
        int n;
        scanf("%d%d",&n,&mod);
        Mat.a[0][0] = 5;
        Mat.a[0][1] = 12;
        Mat.a[1][0]= 2;
        Mat.a[1][1] = 5;
        Matri tt;
        n = (PowerMod(2,n,(mod-1)*(mod+1)) + 1);
        tt = Pow(n);
        int ans = (tt.a[0][0]*2 - 1)%mod;
        printf("Case #%d: %d
",cas++,ans);
    }
    return 0;
}