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编辑  收藏