题目大意:求不定方程x^2-n*y^2=1的第k大的解
思路:Pell方程的递推公式用矩阵表示,然后用快速幂求解。
代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int mod=8191;
struct matrix{
int a[3][3];
};
matrix operator + (const matrix &a1,const matrix &b1){
matrix ret;
for(int i=0;i<2;++i){
for(int j=0;j<2;++j){
ret.a[i][j]=a1.a[i][j]+b1.a[i][j];
ret.a[i][j]%=mod;
}
}
return ret;
}
matrix operator *(const matrix& b1,const matrix &b2){
matrix ret;
for(int i=0;i<2;++i){
for(int j=0;j<2;++j){
ret.a[i][j]=0;
for(int k=0;k<2;++k){
ret.a[i][j]+=(b1.a[i][k]*b2.a[k][j])%mod;
ret.a[i][j]%=mod;
}
}
}
return ret;
}
matrix pow_mod(matrix d,int t){
matrix ret;
ret.a[0][0]=ret.a[1][1]=1;
ret.a[1][0]=ret.a[0][1]=0;
while(t){
if(t&1){ret=ret*d;
}
t>>=1;
d=d*d;
}
return ret;
}
matrix kk;
int main(){
// freopen("data.txt","r",stdin);
int n,k;
while(scanf("%d%d",&n,&k)!=EOF){
int x,y;
int sn=sqrt((double)n);
if(sn*sn==n){printf("No answers can meet such conditions\n");continue;}
bool f=0;
for(x=2;;x++){
for(y=1;y<x;y++){
if(x*x-n*y*y==1){f=1;break;}
if(x*x-n*y*y<1)break;
}
if(f)break;
}
kk.a[0][0]=x%mod;
kk.a[0][1]=n*y%mod;
kk.a[1][0]=y%mod;
kk.a[1][1]=x%mod;
kk=pow_mod(kk,k-1);
int xk=kk.a[0][0]*x+kk.a[0][1]*y;
xk%=mod;
printf("%d\n",xk);
}
return 0;
}