首页 > 其他 > 详细

POJ2417 Discrete Logging【BSGS】

时间:2017-03-07 20:40:41      阅读:268      评论:0      收藏:0      [点我收藏+]
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;
}

 

 

POJ2417 Discrete Logging【BSGS】

原文:http://www.cnblogs.com/shenben/p/6516478.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!