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; }