HDU 4549M斐波那契數列(矩陣快速冪+費馬小定理)
M斐波那契數列
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 993 Accepted Submission(s): 293
Problem Description
M斐波那契數列F[n]是一種整數數列,它的定義如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
現在給出a, b, n,你能求出F[n]的值嗎?
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
現在給出a, b, n,你能求出F[n]的值嗎?
Input
輸入包含多組測試資料;
每組資料佔一行,包含3個整數a, b, n( 0 <= a, b, n <= 10^9 )
每組資料佔一行,包含3個整數a, b, n( 0 <= a, b, n <= 10^9 )
Output
對每組測試資料請輸出一個整數F[n],由於F[n]可能很大,你只需輸出F[n]對1000000007取模後的值即可,每組資料輸出一行。
Sample Input
0 1 0
6 10 2
Sample Output
0
60
Source
題目大意:題目易懂,主要是資料太大。自己瞭解的降冪公式沒有這麼吊。這個也不需要討論。如果mod為質數的話,根據費馬小定理可以得到:a^p%(mod)=a^(p%(mod-1)). mod為質數
解題思路:根據題意,慢慢可以推公式。可以得到他們a,b的次數實際上是服從斐波那契數列的,不過需要用到矩陣的快速冪去計算。然後就是快速冪把結果算出來。
詳解見程式碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;
int mo=1e9+7;
__int64 ret[2][2],tmp[2][2],p[2][2];
__int64 n;
void init() //初始化
{
ret[0][0]=1; ret[0][1]=1;
ret[1][0]=1; ret[1][1]=0;
p[0][0]=1; p[0][1]=1;
p[1][0]=1; p[1][1]=0;
}
void cal1() //!(n&1)
{
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
tmp[i][j]=p[i][j];
p[i][j]=0;
}
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)
p[i][j]=(p[i][j]+tmp[i][k]*tmp[k][j])%(mo-1);
}
void cal2() //n&1
{
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
tmp[i][j]=ret[i][j];
ret[i][j]=0;
}
for(i=0;i<2;i++)
for(j=0;j<2;j++)
for(k=0;k<2;k++)
ret[i][j]=(ret[i][j]+tmp[i][k]*p[k][j])%(mo-1);
}
void fastmi() //矩陣的快速冪
{
init();
n-=3;
while(n)
{
if(n&1)
cal2();
cal1();
n>>=1;
}
}
__int64 pow(__int64 base,__int64 p) //快速冪
{
__int64 ans=1;
while(p)
{
if(p&1)
ans=(ans*base)%mo;
base=(base*base)%mo;
p>>=1;
}
return ans;
}
int main()
{
__int64 a,b;
while(~scanf("%I64d%I64d%I64d",&a,&b,&n))
{
__int64 ans1,ans2,res1,res2;
if(n==0) ans1=1,ans2=0;
else if(n==1) ans1=0,ans2=1;
else if(n==2) ans1=1,ans2=1;
else
{
fastmi();
ans2=(ret[0][0]+ret[0][1])%(mo-1); //b的次數
ans1=(ret[1][0]+ret[1][1])%(mo-1); //a的次數
//printf("%I64d %I64d\n",ans1,ans2);
}
res1=pow(a,ans1);
res2=pow(b,ans2);
__int64 res=(res1*res2)%mo;
printf("%I64d\n",res);
}
return 0;
}
相關文章
- HDU 4549 M斐波那契數列(矩陣快速冪+費馬小定理)矩陣
- 從斐波那契到矩陣快速冪矩陣
- hdu 3117矩陣+斐波那契數列矩陣
- 斐波那契數列Ⅳ【矩陣乘法】矩陣
- 費馬小定理 + 費馬大定理 + 勾股數的求解 + 快速冪 + 矩陣快速冪 【模板】矩陣
- 斐波那契數列的第N項(1≤n≤10^18 矩陣快速冪)矩陣
- HDU 1588 斐波那契數列數列變形和矩陣連乘矩陣
- 斐波那契數列
- 斐波那契數列(Java)Java
- 斐波那契數列 (C#)C#
- PHP 與斐波那契數列PHP
- 斐波那契數列詳解
- 斐波那契數
- js實現斐波那契數列JS
- 斐波那契數列js 實現JS
- 斐波那契數列演算法演算法
- 演算法(1)斐波那契數列演算法
- 面試題9-斐波那契數列面試題
- [C103] 斐波那契數列
- [亂搞]斐波那契數列與gcd之間一個有趣的定理GC
- 使用Python實現斐波那契數列Python
- JavaScript 實現:輸出斐波那契數列JavaScript
- js迭代器實現斐波那契數列JS
- 演算法一:斐波那契阿數列演算法
- 斐波那契數列的分治法計算
- 斐波那契數列的python實現Python
- 大數斐波那契數列的演算法演算法
- HDU2813Interesting Fibonacci(斐波那契數列+迴圈節)REST
- Leedcode-斐波那契數
- 斐波那契數列三種實現函式函式
- 計算斐波那契數列的演算法演算法
- 劍指offer-9-斐波那契數列-javaJava
- 斐波那契數列演算法 JS 實現演算法JS
- 斐波那契查詢
- 斐波那契數列的通項公式及證明公式
- 每日一算 -- 斐波那契數列型別題型別
- 斐波那契數列 多語言實現 筆記筆記
- js計算斐波那契數列程式碼例項JS