#P10252. k-斐波那契
前言(Front talk)
数学一定要好好学,虽然学的时候比较难懂,但是想出来方法就会非常简单
网址(Website)
题目(Problem)
已知
范围:
题解(Solution)
代码(Code)
#include<bits/stdc++.h>
#define For(i,l,r) for(int i=l;i<=r;i++)
#define Rof(i,l,r) for(int i=l;i>=r;i--)
using namespace std;
#define int long long
inline int input(){int x;return cin>>x,x;}
int n,p;
struct Jz{
int a[4][4],n=2,m=2;
Jz(){memset(a,0,sizeof(a));}
Jz operator*(Jz y){
Jz res;For(k,1,2) For(i,1,2) For(j,1,2){
res.a[i][k]=(res.a[i][k]+a[i][j]*y.a[j][k]%p)%p;
}return res;
}
};
inline Jz ksm(int k){
Jz res;res.a[1][1]=res.a[2][2]=1;
Jz x;x.a[1][1]=x.a[1][2]=x.a[2][1]=1;
while(k){
if(k&1) res=res*x;
x=x*x,k>>=1;
}return res;
}
inline int g(int a,int b,int &x,int &y){
if(!b) return x=1,y=0,a;
int d=g(b,a%b,y,x);
y-=a/b*x;return d;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string str("kfib");
freopen((str+".in").c_str(),"r",stdin);
freopen((str+".out").c_str(),"w",stdout);
cin>>n>>p;
Jz ans=ksm(n);
int a=ans.a[1][1],k,b;
g(a,p,k,b);
cout<<(k%p+p)%p<<'\n';
//这是另一种(标准的)方法
// int a=1,b=ans.a[1][1],c=p,X,Y;
// int d=g(b,c,X,Y),r=c/d;
// if(a%d) cout<<"None\n";
// else cout<<(a/d*X%r+r)%r<<'\n';
return 0;
}