高次同余方程(Baby-Step Giant-Step)

Discrete LogarithmProblem  网页链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=121425#problem/D 传送门:nefu

题目描述:



题目大意:


模板题,a^x=b(mod p) p为素数和不是素数都可以

代码实现:

#include <iostream>

#include <cmath>

#include <cstdio>

#include <cstring>

#define MOD 76543

 

using namespace std;

inths[MOD],head[MOD],next[MOD],id[MOD],top;

void insert1(int x,int y)

{

    int k=x%MOD;

    hs[top]=x;

    id[top]=y;

    next[top]=head[k];

    head[k]=top++;

}

 

int find1(int x)

{

    int k=x%MOD;

    for(int i=head[k];i!=-1;i=next[i])

        if(hs[i]==x)

        return id[i];

    return -1;

}

 

int BSGS(int a,int b,int n)

{

    memset(head,-1,sizeof(head));

    top=1;

    if(b==1)

        return 0;

    int m=sqrt(n*1.0),j;

    long long x=1,p=1;

    for(int i=0;i<m;i++,p=p*a%n)

        insert1(p*b%n,i);

    for(long long i=m; ;i+=m)

    {

        if((j=find1(x=x*p%n))!=-1)

            return i-j;

        if(i>n)

            break;

    }

    return -1;

}

 

int main()

{

    int p,a,b;

    scanf("%d",&p);

    while(scanf("%d",&a)!=EOF)

    {

        if(a==0)

            break;

        else

        {

            scanf("%d",&b);

            b=b%p;

            int tmp=BSGS(a,b,p);

            if(tmp<0)

                puts("0");

            else printf("%d\n",tmp);

        }

    }

    return 0;

}

 

Discrete Logging

Time Limit: 5000MS

Memory Limit: 65536K

Total Submissions: 5015

Accepted: 2277

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, findan integer L such that 

    BL == N (mod P)

Input

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

Output

For each line print thelogarithm on a separate line. If there are several, print the smallest; ifthere 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 problemrequires a well known result in number theory that is probably expected of youfor 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-Bpseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichaelnumbers, are pseudoprimes for every base between 2 and P-1. A corollary toFermat's theorem is that for any m 

  B(-m) == B(P-1-m) (mod P) .

Source

Waterloo Local 2002.01.26

 

题目大意:

同上,只需要对输入和输出稍作修改即可。

代码实现:

#include <iostream>

#include <cmath>

#include <cstdio>

#include <cstring>

#define MOD 76543

 

using namespace std;

inths[MOD],head[MOD],next[MOD],id[MOD],top;

void insert1(int x,int y)

{

    int k=x%MOD;

    hs[top]=x;

    id[top]=y;

    next[top]=head[k];

    head[k]=top++;

}

 

int find1(int x)

{

    int k=x%MOD;

    for(int i=head[k];i!=-1;i=next[i])

        if(hs[i]==x)

        return id[i];

    return -1;

}

 

int BSGS(int a,int b,int n)

{

    memset(head,-1,sizeof(head));

    top=1;

    if(b==1)

        return 0;

    int m=sqrt(n*1.0),j;

    long long x=1,p=1;

    for(int i=0;i<m;i++,p=p*a%n)

        insert1(p*b%n,i);

    for(long long i=m; ;i+=m)

    {

        if((j=find1(x=x*p%n))!=-1)

            return i-j;

        if(i>n)

            break;

    }

    return -1;

}

 

int main()

{

    int p,a,b;

   while(scanf("%d%d%d",&p,&a,&b)!=EOF)

    {

        if(a==0&&p==0&&b==0)

            break;

        else

        {

            b=b%p;

            int tmp=BSGS(a,b,p);

            if(tmp<0)

                puts("no solution");

            else printf("%d\n",tmp);

        }

    }

    return 0;

}

 

Clever Y

Time Limit: 5000MS

Memory Limit: 65536K

Total Submissions: 7919

Accepted: 1971

Description

Little Y finds there is a veryinteresting formula in mathematics:

XY mod Z = K

Given XYZ, we all know how to figure out K fast. However, given XZK, could you figure out Y fast?

 

Input

Input data consists of no morethan 20 test cases. For each test case, there would be only one line containing3 integers XZK (0 ≤ XZK ≤ 109). 
Input file ends with 3 zeros separated by spaces. 

Output

For each test case output oneline. Write "No Solution" (without quotes) if you cannot find afeasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

Sample Input

5 58 33

2 4 3

0 0 0

Sample Output

9

No Solution

Source

POJ Monthly--2007.07.08, Guo, Huayang

 

题目大意:

同上,只需对输入输出稍作修改即可!

代码实现:

#include <iostream>

#include <cmath>

#include <cstdio>

#include <cstring>

#define MOD 76543

 

using namespace std;

inths[MOD],head[MOD],next[MOD],id[MOD],top;

void insert1(int x,int y)

{

    int k=x%MOD;

    hs[top]=x;

    id[top]=y;

    next[top]=head[k];

    head[k]=top++;

}

 

int find1(int x)

{

    int k=x%MOD;

    for(int i=head[k];i!=-1;i=next[i])

        if(hs[i]==x)

        return id[i];

    return -1;

}

 

int BSGS(int a,int b,int n)

{

    memset(head,-1,sizeof(head));

    top=1;

    if(b==1)

        return 0;

    int m=sqrt(n*1.0),j;

    long long x=1,p=1;

    for(int i=0;i<m;i++,p=p*a%n)

        insert1(p*b%n,i);

    for(long long i=m; ;i+=m)

    {

        if((j=find1(x=x*p%n))!=-1)

            return i-j;

        if(i>n)

            break;

    }

    return -1;

}

 

int main()

{

    int p,a,b;

   while(scanf("%d%d%d",&a,&p,&b)!=EOF)

    {

        if(a==0&&p==0&&b==0)

            break;

        else

        {

            b=b%p;

            int tmp=BSGS(a,b,p);

            if(tmp<0)

                puts("No Solution");

            else printf("%d\n",tmp);

        }

    }

    return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值