hdu 5451(矩阵 +Fibonacci )

来源:互联网 发布:mac 谷歌浏览器 utf 8 编辑:程序博客网 时间:2024/05/16 11:20

题意:求 [(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\n",cas++,ans);    }    return 0;}




0 0
原创粉丝点击