隐藏页面特效

POJ2417 Discrete Logging【BSGS】

Discrete Logging
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 5577   Accepted: 2494

Description

Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that 
B
L
== N (mod P)

Input

Read several lines of input, each containing P,B,N separated by a space.

Output

For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print "no solution".

Sample Input

5 2 1 5 2 2 5 2 3 5 2 4 5 3 1 5 3 2 5 3 3 5 3 4 5 4 1 5 4 2 5 4 3 5 4 4 12345701 2 1111111 1111111121 65537 1111111111

Sample Output

0 1 3 2 0 3 1 2 0 no solution no solution 1 9584351 462803587

Hint

The solution to this problem requires a well known result in number theory that is probably expected of you for Putnam but not ACM competitions. It is Fermat's theorem that states 
B
(P-1)
== 1 (mod P)

for any prime P and some other (fairly rare) numbers known as base-B pseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichael numbers, are pseudoprimes for every base between 2 and P-1. A corollary to Fermat's theorem is that for any m 
B
(-m)
== B
(P-1-m)
(mod P) .

Source

 
高次同余方程。   BL == N (mod P)求解最小的L
BSGS模板题目。
#include<cmath> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; struct Thash{ static const int MOD=233333; static const int MAXN=1e6+5; int tot,head[MOD+100],next[MAXN],h[MAXN],val[MAXN]; inline void clear(){tot=0;memset(head,0,sizeof head);} inline void insert(int H,int VAL){ for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H){val[i]=VAL;return ;} h[++tot]=H;val[tot]=VAL;next[tot]=head[H%MOD];head[H%MOD]=tot; } inline int get(int H){ for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H) return val[i]; return 0; } }M; inline ll fpow(ll a,ll p,ll mod){ int res=1; for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod; return res; } int BSGS(ll A,ll B,ll mod){ A%=mod; if(!A){ if(!B) return 1; return -1; } ll m=sqrt(mod)+1,ni=fpow(A,mod-m-1,mod); ll t=1,y=1; M.clear(); M.insert(1,m+1); for(int i=1;i<m;i++){ t=t*A%mod; if(!M.get(t)) M.insert(t,i); } for(int i=0;i<m;i++){ int u=M.get(B*y%mod); if(u){ if(u==m+1) u=0; return i*m+u; } y=y*ni%mod; } return -1; } int main(){ int a,b,c,ans(-1); while(scanf("%d%d%d",&c,&a,&b)==3){ ans=BSGS(a,b,c); if(~ans) printf("%d\n",ans); else puts("no solution"); } return 0; }

 

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/6516478.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(595)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示