斐波拉切
求f(n)%p
描述:f(0)=1;f(1)=1;f(2)=2;f(n)=f(n-1)+f(n-2);
输入:两个整数n和p;
输出:f(n)%p;
方法一:矩阵快速模幂
struct SS{int S[2][2];}A;
A.S[0][0]=0;A.S[0][1]=1;A.S[1][0]=1;A.S[1][1]=1;
A=A^n;
f(n)=A.S[1][1];
1、C++递归实现(这个方法是我常用的):
View Code
1 #include<iostream> 2 using namespace std; 3 4 struct SS{int S[2][2];}; 5 int n=2,p; 6 7 SS matrix_mult(SS A,SS B) 8 { 9 SS C; 10 int i,j,k; 11 for(i=0;i<n;i++) 12 { 13 for(j=0;j<n;j++) 14 { 15 C.S[i][j]=0; 16 for(k=0;k<n;k++) 17 { 18 C.S[i][j]+=A.S[i][k]*B.S[k][j]; 19 } 20 C.S[i][j]=C.S[i][j]%p; 21 } 22 } 23 return C; 24 } 25 26 SS matrix_pow_mod(SS A,int n) 27 { 28 if(n==1||n==0) return A; 29 SS T; 30 T=matrix_pow_mod(A,n/2); 31 T=matrix_mult(T,T); 32 if(n%2==1) T=matrix_mult(A,T); 33 return T; 34 } 35 36 int main() 37 { 38 int n; 39 SS A,ans; 40 A.S[0][0]=0;A.S[0][1]=1;A.S[1][0]=1;A.S[1][1]=1;//这里总是把A.S[1][0] A.S[0][1]; 以后注意 41 while(cin>>n>>p) 42 { 43 ans=matrix_pow_mod(A,n); 44 cout<<ans.S[1][1]<<endl; 45 } 46 return 0; 47 }
2、C++非递归实现(平时老是写不好):
View Code
1 #include<iostream> 2 using namespace std; 3 4 struct SS{int S[2][2];}; 5 int p,n=2; 6 7 SS matrix_mult(SS A,SS B) 8 { 9 SS C; 10 int i,j,k; 11 for(i=0;i<n;i++) 12 { 13 for(j=0;j<n;j++) 14 { 15 C.S[i][j]=0; 16 for(k=0;k<n;k++) 17 { 18 C.S[i][j]+=A.S[i][k]*B.S[k][j]; 19 } 20 C.S[i][j]=C.S[i][j]%p; 21 } 22 } 23 return C; 24 } 25 26 SS matrix_pow_mod(SS A,int n) 27 { 28 if(n==1||n==0) return A; 29 SS T,ans; 30 ans.S[0][0]=1;ans.S[0][1]=0;ans.S[1][0]=0;ans.S[1][1]=1; 31 T=A; 32 while(n>=1) 33 { 34 if(n%2==1) ans=matrix_mult(ans,T); 35 T=matrix_mult(T,T); 36 n=n/2; 37 } 38 return ans; 39 } 40 41 int main() 42 { 43 int n; 44 SS A,ans; 45 A.S[0][0]=0;A.S[0][1]=1;A.S[1][0]=1;A.S[1][1]=1; 46 while(cin>>n>>p) 47 { 48 ans=matrix_pow_mod(A,n); 49 cout<<ans.S[1][1]<<endl; 50 } 51 return 0; 52 }
方法二:使用斐波拉切求模后的周期性来解:
由于斐波拉切数模上一个整数 p 会形成周期,所以我们打表这个周期就行了,一般这个周期不会很大。
View Code
1 #include<iostream> 2 #define N 100000 3 #include<fstream> 4 5 using namespace std; 6 7 int ans[N]; 8 9 int work(int p) 10 { 11 int i=2; 12 do 13 { 14 ans[i]=(ans[i-1]+ans[i-2])%p; 15 if((ans[i-1]==1)&&(ans[i]==1)) break; 16 i++; 17 }while(1); 18 return i-1; 19 } 20 21 int main() 22 { 23 int p,n,t; 24 ans[0]=1; 25 ans[1]=1; 26 while(cin>>n>>p) 27 { 28 t=work(p); 29 cout<<ans[n%t]<<endl; 30 } 31 return 0; 32 }