# BZOJ5104 : Fib数列

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<ll,ll>PI;
const int P=1000000009,K=32000;
ll X,ans=-1,g[K+5][2][2],w[K+5][2];map<PI,int>T;
inline ll po(ll a,ll b,ll P){ll t=1;for(;b;b>>=1,a=a*a%P)if(b&1)t=t*a%P;return t;}
ll ToneLLi_Shanks(ll n,ll p){
if(!n)return 0;
if(p==2)return n&1?1:-1;
if(po(n,p>>1,p)!=1)return -1;
if(p&2)return po(n,p+1>>2,p);
int s=__builtin_ctzll(p^1);
ll q=p>>s,z=2;
for(;po(z,p>>1,p)==1;z++);
ll c=po(z,q,p);
ll r=po(n,q+1>>1,p);
ll t=po(n,q,p),tmp;
for(int m=s,i;t!=1;){
for(i=0,tmp=t;tmp!=1;i++)tmp=tmp*tmp%p;
for(;i<--m;)c=c*c%p;
r=r*c%p;
c=c*c%p;
t=t*c%p;
}
return r;
}
inline void mul(ll a[][2],ll b[][2],ll f[][2]){
static ll c[2][2];
c[0][0]=(a[0][0]*b[0][0]+a[0][1]*b[1][0])%P;
c[0][1]=(a[0][0]*b[0][1]+a[0][1]*b[1][1])%P;
c[1][0]=(a[1][0]*b[0][0]+a[1][1]*b[1][0])%P;
c[1][1]=(a[1][0]*b[0][1]+a[1][1]*b[1][1])%P;
f[0][0]=c[0][0];
f[0][1]=c[0][1];
f[1][0]=c[1][0];
f[1][1]=c[1][1];
}
void work(ll X,ll Y){
T.clear();
for(int i=0;i<K;i++){
ll a=(g[i][0][0]*X+g[i][0][1]*Y)%P;
ll b=(g[i][1][0]*X+g[i][1][1]*Y)%P;
T[PI(a,b)]=i;
}
for(int i=1;i<=K;i++){
map<PI,int>::iterator it=T.find(PI(w[i][0],w[i][1]));
if(it!=T.end()){
ll now=i*K-it->second;
if(ans==-1||ans>now)ans=now;
return;
}
}
}
void solve(ll A,ll B,ll C){
ll d=((B*B-4*A*C)%P+P)%P;
d=ToneLLi_Shanks(d,P);
if(d<0)return;
d=(d%P+P)%P;
ll t=po(A*2%P,P-2,P);
work(X,((-B-d)*t%P+P)%P);
work(X,((-B+d)*t%P+P)%P);
}
int main(){
scanf("%lld",&X);
if(X>=P)return puts("-1"),0;
ll A=P-1,B=X,C=X*X%P;
g[0][0][0]=1;
g[0][1][1]=1;
g[1][0][1]=1;
g[1][1][0]=1;
g[1][1][1]=1;
for(int i=2;i<=K;i++)mul(g[i-1],g[1],g[i]);
w[0][1]=1;
for(int i=1;i<=K;i++){
w[i][0]=(g[K][0][0]*w[i-1][0]+g[K][0][1]*w[i-1][1])%P;
w[i][1]=(g[K][1][0]*w[i-1][0]+g[K][1][1]*w[i-1][1])%P;
}
solve(A,B,(C-1+P)%P);
solve(A,B,(C+1)%P);
return printf("%lld",ans),0;
}


posted @ 2017-11-26 00:35 Claris 阅读(...) 评论(...) 编辑 收藏