Fibonacci质数的定义:
若某Fibonacci数与任何比它小的Fibonacci数互质,那么它就是Fibonacci质数。
但是哪些的Fibonacci数才是Fibonacci质数呢?这里先给出结论:
-
F(3)和F(4)是Fibonacci质数;从F(5)开始,某项为Fibonacci质数当且仅当它的项数为质数
-
第k小的Fibonacci质数是以质数数列中的第k个数为项数的Fibonacci数( 除F(3)和F(4)之外 )
证明过程:https://www.cnblogs.com/allensun/archive/2011/01/27/1946282.html
处理出前500000个质数
然后快速幂求斐波那契
3和m互质,所以除以3就乘以3的乘法逆元就好了
#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
const int N=7500005;
int prime[N];
ll MOD,n,mod;
void getPrime(){
fo(i,2,7500000){
if(!prime[i])prime[++prime[0]]=i;
for(int j=1; j<=prime[0] && i*prime[j]<=7500000; j++){
prime[i*prime[j]] = prime[j];
if(i%prime[j]==0)break;
}
}
// cout<<prime[0];
}
// a,p互质,求a的乘法逆元
void exgcd(int a,int b,int &x,int &y,int &d){
if(!b){x=1;y=0;d=a;}else exgcd(b,a%b,y,x,d),y-=a/b*x;
}
inline int inv(int a,int p){
int x,y,d;exgcd(a,p,x,y,d);x=(x%p+p)%p;return x;
}
// 快速幂求斐波那契
void mul(ll f[2], ll a[2][2]){
ll c[2];
memset(c,0,sizeof c);
for(int j=0; j<2; j++){
for(int k=0; k<2; k++){
c[j] = (c[j] + (ll)f[k]*a[k][j])%mod;
}
}
memcpy(f,c,sizeof(c));
}
void mulself(ll a[2][2]){
ll c[2][2];
memset(c,0,sizeof(c));
for(int i=0; i<2; i++){
for(int j=0;j<2; j++){
for(int k=0; k<2; k++){
c[i][j] = (c[i][j]+(ll)a[i][k]*a[k][j])%mod;
}
}
}
memcpy(a,c,sizeof(c));
}
ll fib(ll n){
ll f[2] = {0,1};
ll A[2][2] = {{0,1},{1,1}};
ll t = n;
for(;t;t>>=1){
if(t&1)mul(f, A);
mulself(A);
}
return f[0];
}
inline void print(int n){
int inv3=inv(3,mod);n=1ll*inv3*n%mod; // 3 和mod 互质
for(int i=100000000;i;i/=10)
if((n/i)%10==0)putchar('*');
else break;
printf("%d\n",n);
}
int main(){
getPrime();
while(cin>>n>>mod){
if(n==1){
print(2);
}else if(n==2){
print(3);
}else{
print(fib(prime[n]));
}
}
return 0;
}