BZOJ_3239_Discrete Logging_BSGS
BZOJ_3239_Discrete Logging_BSGS
题意:Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 2 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that BL == N (mod P)
分析:BSGS裸题
数据很水,少了很多特判依然能过
BSGS思想核心思想:根号预处理+哈希/map
代码:
// luogu-judger-enable-o2 #include <stdio.h> #include <string.h> #include <algorithm> #include <map> #include <math.h> using namespace std; #define LL long long map<LL,int> mp; LL qp(LL x,LL y,LL mod){ LL re=1; while(y){ if(y&1ll)re=re*x%mod; x=x*x%mod; y>>=1ll; } return re; } void exgcd(LL a,LL b,LL &x,LL &y,LL &p){ if(!b){x=1;y=0;p=a;return ;} exgcd(b,a%b,y,x,p); y-=(a/b)*x; } LL BSGS(LL n,LL a,LL b){ if(n==1)if(!b)return a!=1; else return -1; if(b==1)if(a)return 0; else return -1; if(a%n==0)if(!b)return 1; else return -1; LL m=ceil(sqrt(n)),d=1,base=1; mp.clear(); for(int i=0;i<m;i++) { if(!mp.count(base))mp[base]=i; base=(base*a)%n; } for(int i=0;i<m;i++) { LL x,y,s; exgcd(d,n,x,y,s); x=(x*b%n+n)%n; if(mp.count(x))return i*m+mp[x]; d=(d*base)%n; } return -1; } int main() { LL n,a,b; while(scanf("%lld%lld%lld",&n,&a,&b)!=EOF) { LL x=BSGS(n,a,b); if(x==-1)puts("no solution"); else printf("%lld\n",x); } }