HDOJ 4549 - M斐波那契数列 费马小定理,矩阵乘法

      矩阵乘法求线性关系的数列...而本数列不是线性关系..无法对F(n)构造矩阵直接用矩阵乘法解决...

      不难发现若取log F(n)...则log F(n) = log F(n-1) + log F(n-2)....可以转化成线性关系...

      引入一个非常重要的定理....费马小定理...描述: 假如p是质数,且(a,p)=1,那么 a^(p-1) ≡1(mod p)

      本题要注意..提供的1000000007就是质数...且底数a,b,都不会大于等于p...也就是(a,p)与(b,p)恒为1...

      联系费马小定里那么有对于任意的 a^k %m=a^(k%(m-1)) %m

      推出这个结论..本题就可以通过进行多次矩阵乘法来解决了...


Program:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#define ll long long
#define oo 1000000007
#define MAXN 1005
using namespace std;
struct node
{
       ll s[2][2];
}p;
node mul(node a,node b)
{
       int i,j,k;
       node h;
       memset(h.s,0,sizeof(h.s));
       for (k=0;k<2;k++)
         for (i=0;i<2;i++)
            for (j=0;j<2;j++)
               h.s[i][j]=(h.s[i][j]+a.s[i][k]*b.s[k][j])%(oo-1);
       return h;
}
ll Fibonacci(int n)
{
       node h;
       h.s[0][0]=h.s[1][1]=1;
       h.s[0][1]=h.s[1][0]=0;
       p.s[0][0]=0;
       p.s[0][1]=p.s[1][0]=p.s[1][1]=1;
       int i;
       for (i=0;i<=30;i++)
       {
              if (n & 1<<i) h=mul(h,p);
              p=mul(p,p);
       }
       return h.s[1][0];
}
ll getdata(ll a,ll n)
{ 
       int i;
       ll p=a,k=1;
       for (i=0;i<=30;i++)
       { 
              if (n & 1<<i) k=(k*p)%oo; 
              p=(p*p)%oo;
       }       
       return k;
}
ll getans(ll a,ll b,ll n)
{
       if (n==0) return a;
       if (n==1) return b;  
       a=getdata(a,Fibonacci(n-1));
       b=getdata(b,Fibonacci(n));
       return a*b%oo;
}
int main()
{     
       ll a,b,n;
       while (~scanf("%I64d%I64d%I64d",&a,&b,&n))
       {
              printf("%I64d\n",getans(a,b,n));
       }
       return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值