HDU 4549 M斐波那契数列(矩阵快速幂)

题目链接:M斐波那契数列

题意:$F[0]=a,F[1]=b,F[n]=F[n-1]*F[n-2]$。给定$a,b,n$,求$F[n]$。

题解:暴力打表后发现$ F[n]=a^{fib(n-1)} * b^{fib(n)} $

斐波那契数列可用矩阵快速幂求解。但是此题中n较大,fib会爆掉。这时候需要引入费马小定理优化。

证明:$a^x \% p = a^{x \%(p-1)} \%p$

1. $a^x \% p = a^{x \% (p-1) + x/(p-1)*(p-1)} \% p$

2. $a^x \% p = a^{x \% (p-1)} * a^{x/(p-1)*(p-1)} \%p$

3. $a^{x/(p-1)*(p-1)} \% p= ({a^{p-1}}) ^ {(x/(p-1))} \%p = 1^ {(x/(p-1))}$

把3式带入2式,即可证明。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define N 2
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 const ll mod=1000000007;
10 
11 struct mat
12 {
13     ll m[N][N]=
14     {
15      {1,1},
16      {1,0}
17     };
18 };
19 
20 mat mul(mat a,mat b,ll p)
21 {
22     mat ans;
23     int i,j,k;
24     for(i=0;i<N;i++)
25     for(j=0;j<N;j++)
26     ans.m[i][j]=0;
27 
28     for(i=0;i<N;i++)
29     for(j=0;j<N;j++)
30     for(k=0;k<N;k++)
31     ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j])%p;
32     return ans;
33 }
34 
35 ll matpow(ll n,ll p)
36 {
37     if(n<0) return 0;
38     mat ans,tmp;
39     int i,j;
40     for(int i=0;i<N;i++)
41     for(int j=0;j<N;j++)
42     ans.m[i][j]=0;
43 
44     ans.m[0][0]=0;
45     ans.m[1][0]=1;
46     while(n)
47     {
48         if(n&1) ans=mul(tmp,ans,p);
49         tmp=mul(tmp,tmp,p);
50         n=n>>1;
51     }
52     return ans.m[0][0]%p;
53 }
54 
55 ll fast_mod(ll a,ll b,ll p){
56     ll res=1;
57     while(b){
58         if(b&1) res=(res*a)%p;
59         a=(a*a)%p;
60         b>>=1;
61     }
62     return res;
63 }
64 
65 int main(){
66     ll n,a,b;
67 
68     while(scanf("%lld%lld%lld",&a,&b,&n)!=EOF){
69         if(n==0){
70             printf("%lld
",a);
71             continue;
72         }
73         else if(n==1){
74             printf("%lld
",b);
75             continue;
76         }
77         else if(a==0||b==0){
78             printf("0
");
79             continue;
80         }
81         ll m1=matpow(n-1,mod-1);
82         ll m2=matpow(n,mod-1);
83         ll ans=(fast_mod(a,m1,mod)*fast_mod(b,m2,mod))%mod;
84         printf("%lld
",ans%mod);
85     }
86 
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/pavtlly/p/9811333.html