# BZOJ5104 二次剩余板子

https://www.lydsy.com/JudgeOnline/problem.php?id=5104

https://www.zybuluo.com/mdeditor#1210359

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
#include<ctime>
#include<cmath>
#define re register
#define rep(i,s,t) for(re int i=s;i<=t;++i)
using namespace std;
typedef long long ll;
const int sq5=383008016,ny2=500000005,mod=1000000009,inf=0x7fffffff;
int n,w;
map<int,int>ma;
struct com{
int x,y;
inline com operator*(const com &a){
return (com){(1ll*x*a.x+1ll*y*a.y%mod*w)%mod,(1ll*x*a.y+1ll*y*a.x)%mod};
}
};
inline int fp(int a,int b){
int res=1;
for(;b;b>>=1,a=1ll*a*a%mod)
if(b&1)
res=1ll*res*a%mod;
return res;
}
inline int sq(int n){
if(fp(n,(mod-1)/2)!=1)return 0;
int a;
for(a=rand();fp((1ll*a*a%mod-n+mod)%mod,(mod-1)/2)==1;a=rand());
com x=(com){a,mod-1},ans=(com){1,0};
int y=(mod+1)/2;w=(1ll*a*a%mod+mod-n)%mod;
for(;y;y>>=1,x=x*x)
if(y&1)ans=ans*x;
return ans.x;
}
inline int BSGS(int t,int n){
int blo=sqrt(mod),ny=fp(t,mod-2),tmp=n;
ma.clear(),ma[n]=mod;
rep(i,1,blo-1)tmp=1ll*tmp*ny%mod,ma[tmp]=!ma[tmp]?i:ma[tmp];
if(ma[1])return ma[1]%mod;
tmp=1;t=fp(t,blo);
rep(i,1,blo){
tmp=1ll*tmp*t%mod;
if(ma[tmp])
return(i*blo+ma[tmp])%mod;
}
return -1;
}
int main(){
srand(time(0));
scanf("%d",&n);
int t=1ll*(sq5+1)*ny2%mod,T=1ll*sq5*n%mod;
int ans=inf,x,y,r0=sq(5ll*n*n%mod+4),r1=sq(5ll*n*n%mod-4);
x=1ll*(T+r0)*ny2%mod;y=BSGS(t,x);if(y>-1&&!(y&1)&&r0)ans=min(ans,y);
x=1ll*(T+mod-r0)*ny2%mod;y=BSGS(t,x);if(y>-1&&!(y&1)&&r0)ans=min(ans,y);
x=1ll*(T+r1)*ny2%mod;y=BSGS(t,x);if(y>-1&&(y&1)&&r1)ans=min(ans,y);
x=1ll*(T+mod-r1)*ny2%mod;y=BSGS(t,x);if(y>-1&&(y&1)&&r1)ans=min(ans,y);
if(ans==inf)puts("-1");
else printf("%d",ans);
return 0;
}
code

posted @ 2018-07-11 17:49  Stump  阅读(316)  评论(0编辑  收藏