斐波那契矩阵幂以及费马小定理求余应用

来源:互联网 发布:李连杰电影 知乎 编辑:程序博客网 时间:2024/05/16 08:17

最近遇到费马小定理的一道应用题,思考了几个小时,理清了思路,终于证明了费马小定理求指数余以及矩阵幂求斐波那契结论;

先入为主(偷懒=_=),上题;

不一样的斐波那契数列(二)

Description

自从荟荟上了奥术课之后,她就觉得自己十分强大,但是万恶的数学老师说我们现在来讨论一下斐波那契数列。荟荟说,我知道。老师说,你知道很好,那么我们今天我们变形一下。

已知

F(0)=a

F(1)=b

F(n)=F(n-1)*F(n-2) (n>=2)

求F(n)

答案mod 1000000007 (1e9+7)


Input

多组数据输入,每组数据第一行输入三个整数a,b,n。

0<=a,b,n<=1e16


Output

对于每组数据输出F(n) mod 1000000007 (1e9+7)

#include<iostream>#include<stdio.h>// a ,b , ab ,a^1b^2 ,a^2b^3 //可以发现 数列F(N)的指数存在斐波那契的变化趋势,//那么直接根据对应关系求出f(N)的 指数,最后用快速幂即可;// 其中 矩阵求求斐波那契以及费马小定理的求余较难,但仔细想想就可以理解;// 1.斐波那契数列 :1,1,2,3,5,8…… //可以由矩阵求的;//构造矩阵A  1 0    系数矩阵B  1  1      //   0 1   1  0//C(0)=A*B^0 = 1 0C(1) = A*B^1= 1  1 C(2)=A*B^2=  2  1   …… //       0 1    1  0      1  1//恰好 有c(N-1).x[1][0]是 F(N)的a的指数,同时C(N-1).x[0][0]是F(N)的b的指数; //归纳说明:由此 可根据矩阵幂来求得斐波那契数;//2 .  费马小定理 的应用;//  有公式: a^(p-1)(MOD p)= 1 (p为质数); 结论:(a^(M%(p-1)) )(mod p)=a^m(mod p);//  证明如下: m=(p-1)*k+l; //a^m(mod p)=( a^(l)*a^(k*(p-1))  )(mod p) //= (a^(l)(mod p)*a^(k*(p-1))(mod p) ) (mod p)//=a^(l)(mod p)//=a^(M%(p-1)(mod p);// 证毕;// 也就是说 反正对指数就可以对其MOD(p-1);// 神奇吧!//3 还有个小问题:底数可不可以取余呢? 可以!// 但是要取余P,而不是p-1;//  道理和乘法求余公式一样的 :(a*b)(mod p)= (a mod  p)*(b mod p )(mod p) ; using namespace std;typedef long long ll;const int MOD = 1000000007;const int MOD2 = 1000000006;struct matrix{ll x[2][2];matrix(){for(int i=0;i<2;i++)for(int j=0;j<2;j++)x[i][j]=0;}}; typedef matrix mat;mat mul(mat a, mat b){mattmp;for(int i=0;i<2;i++)for(int j=0;j<2;j++)for(int k=0;k<2;k++)//费马小定理对指数的应用; tmp.x[i][j] = (tmp.x[i][j] + (ll)a.x[i][k] * b.x[k][j] % MOD2) % MOD2;  return tmp; }mat quickmul(mat a,ll  n){mat ans;for(int i=0;i<2;i++)ans.x[i][i] = 1;while(n>0){if(n&1)ans = mul(ans,a);   //矩阵顺序??? n >>= 1;a = mul(a,a);}return ans;}ll quickmi(ll a, ll p){if(p==0)return 1; ll ans=1;a = a % MOD;p = p % MOD;while(p>0){if(p&1)ans = (ans*a)%MOD;a = (a*a)%MOD;p >>= 1;}return ans;}void print(mat a){for(int i=0;i<2;i++){for(int j=0;j<2;j++)cout<<a.x[i][j]<<' ';cout<<endl;}}int main(){ll a,b,n,ans;while(~scanf("%lld%lld%lld", &a,&b,&n)){if(n>0){a %= MOD;b %= MOD;mat f1, fa;f1.x[0][0]=1;f1.x[1][0]=1;f1.x[0][1]=1;fa = quickmul(f1,n-1);//print(fa); ans = ( quickmi(a, fa.x[1][0] ) *  quickmi(b,fa.x[0][0]) )% MOD; //printf("%lld %lld \n",fa.x[1][0],fa.x[0][0]); //printf("%lld %lld\n",( quickmi(a, fa.x[1][0] % (MOD-1) ) % MOD ), ( quickmi(b,fa.x[0][0]%(MOD-1)) % MOD ) );printf("%lld\n", ans);}else{if(n==0)printf("%d\n", a);else if(n==1)printf("%d\n", b);}}}


阅读全文
0 0
原创粉丝点击