Discrete Logging
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 2831   Accepted: 1391

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
 
经典的高次同余,C是质数,那么A,C互质。A^x = B(mod C)
 /*

 模板题baby_step.
Hash + 扩展欧几里得 +拆分思想 题意:
求A^x = B( mod C )的最小x,其中C是一个质数。
思路:
用普通的babystep_gaint_step即可,具体的做法是这样的,我们把x写成下面这样
的形式:x = i * m + j , 这样上式就可以变成:A^m^i * A^j = B( mod C ),其中m=
ceil( sqrt(C) ),0<=i<m , 0<=j <m,接下去我们先求出所有的A^j % C的值,并且把
它们存到一个hash表中去,接下去就是先处理出A^m%C的值,记作D,现在上式就
变成了这样:D^i * A^j = B( mod C ), 现在我们从0-m-1枚举i,这样D^i的值就
已经知道了,记为DD,下面我们先令A^j 为x,式子就变成了:DD*x = B( mod C )
这个式子是可以通过普通的扩展欧几里得算法求出x的解的(这个方程的x在0-C
内一定会只有一个唯一的解,因为gcd(DD, C) == 1, C是质数),然后在建好的hash
表中查找这个x是否存在,若是存在,则输出此时的i*m+j,就是答案。下面说明一下,
为什么x只需要考虑0-C的解就可以了,如果解存在,则上面已经说明,一定会在0-
C范围内存在一个解,因为是找最小的解,因此这时候的解就是答案;如果不存在
解,我们下面将要说明只需要考虑0-C范围内无解,方程就不会有解了。证明的过程
大致是这样的,首先如果方程在0 -- C内都没有解, 考虑A^x%C的值,由鸽笼原理可
知,余数中势必要出现循环节,而且循环节的长度是C的欧拉函数值,也就是说接下
去的x的余数将进入一个循环,从而将不会得出解了。 */ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<math.h>
using namespace std; typedef __int64 LL;
const int MAX=;
LL A,B,C;
bool Hash[MAX];
LL idx[MAX];
LL val[MAX]; void Ex_gcd(LL a,LL b,LL &x,LL &y)
{
if(b==)
{
x=;
y=;
return ;
}
Ex_gcd(b,a%b,x,y);
LL hxl=x-(a/b)*y;
x=y;
y=hxl;
} LL Euler(LL n)
{
LL i,temp=n;
for(i=;i*i<=n;i++)
{
if(n%i==)
{
while(n%i==)
n=n/i;
temp=temp/i*(i-);
}
}
if(n!=)
temp=temp/n*(n-);
return temp;
} void Insert(LL id,LL num)
{
LL k=num%MAX;
while(Hash[k] && val[k]!=num)
{
k++;
if(k==MAX) k=k-MAX;
}
if(!Hash[k])
{
Hash[k]=;
idx[k]=id;
val[k]=num;
}
}// Hash make LL found(LL num)
{
LL k=num%MAX;
while(Hash[k] && val[k]!=num)
{
k++;
if(k==MAX) k=k-MAX;
}
if(!Hash[k])
{
return -;
}
return idx[k];
}// Hash find LL baby_step(LL a,LL b,LL c)
{
LL M=ceil(sqrt(Euler(c)*1.0));
memset(Hash,false,sizeof(Hash));
memset(idx,-,sizeof(idx));
memset(val,-,sizeof(val));
LL D=;
for(LL i=;i<M;i++)
{
Insert(i,D);
D=D*a%c;
}//maek D; LL res=;
LL x,y;
for(LL i=;i<M;i++)
{
Ex_gcd(res,c,x,y);
LL tmp=x*b%c;
tmp=(tmp%c +c)%c;
LL k=found(tmp);
if(k!=-)
{
return LL(i)*M+k;
}
res=res*D%c;
}
return -;
} int main()
{
while(scanf("%I64d%I64d%I64d",&C,&A,&B)>)
{
LL res=baby_step(A,B,C);
if(res==-)
{
printf("no solution\n");
}
else printf("%I64d\n",res);
}
return ;
}

poj 2417 Discrete Logging ---高次同余第一种类型。babystep_gaint_step的更多相关文章

  1. BSGS算法+逆元 POJ 2417 Discrete Logging

    POJ 2417 Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4860   Accept ...

  2. POJ 2417 Discrete Logging (Baby-Step Giant-Step)

    Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 2819   Accepted: 1386 ...

  3. POJ - 2417 Discrete Logging(Baby-Step Giant-Step)

    d. 式子B^L=N(mod P),给出B.N.P,求最小的L. s.下面解法是设的im-j,而不是im+j. 设im+j的话,貌似要求逆元什么鬼 c. /* POJ 2417,3243 baby s ...

  4. POJ 2417 Discrete Logging ( Baby step giant step )

    Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3696   Accepted: 1727 ...

  5. POJ 2417 Discrete Logging 离散对数

    链接:http://poj.org/problem?id=2417 题意: 思路:求离散对数,Baby Step Giant Step算法基本应用. 下面转载自:AekdyCoin [普通Baby S ...

  6. poj 2417 Discrete Logging(A^x=B(mod c),普通baby_step)

    http://poj.org/problem?id=2417 A^x = B(mod C),已知A,B.C.求x. 这里C是素数,能够用普通的baby_step. 在寻找最小的x的过程中,将x设为i* ...

  7. POJ 2417 Discrete Logging BSGS

    http://poj.org/problem?id=2417 BSGS 大步小步法( baby step giant step ) sqrt( p )的复杂度求出 ( a^x ) % p = b % ...

  8. POJ 2417 Discrete Logging(离散对数-小步大步算法)

    Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 ...

  9. POJ 2417 Discrete Logging

    http://www.cnblogs.com/jianglangcaijin/archive/2013/04/26/3045795.html 给p,a,b求a^n==b%p #include<a ...

随机推荐

  1. setInterval(),setTimeout(),location.reload(true)

    1,setInterval() setInterval()方法可以按照指定的周期来调用函数或表达式,他会不停地调用函数,直到调用clearInterval()方法或窗口关闭.由setInterval( ...

  2. javascript解决getElementById()的bug以及getElementsByClassName的兼容性写法

    <a name="target" href="#">链接</a> <p id="target">文字说明 ...

  3. scrapy实战1,基础知识回顾和虚拟环境准备

        视频地址 https://coding.imooc.com/learn/list/92.html   一. 基础知识回顾     1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...

  4. 2016级算法期末上机-I.难题·ModricWang's Fight with DDLs III

    1126 ModricWang's Fight with DDLs III 思路 由于题目中已经说明了时间经过了正无穷,因此初始位置是不重要的,并且每条边.每个点的地位是均等的.因此到达每个点的概率就 ...

  5. Bootstrap-datepicker日期时间选择器的简单使用

    日期时间选择器 目前,bootstrap有两种日历.datepicker和datetimepicker,后者是前者的拓展. Bootstrap日期和时间组件: 使用示例: 从左到右依次是十年视图.年视 ...

  6. Windows开发经验 - Visual Studio 2017

    1. 调试子进程 Visual Studio 2017及更早的版本原生不支持调试子进程,不确定未来是否会支持.可以通过官方插件让Visual Studio能够调试子进程. https://market ...

  7. redux设计到源码 --- 美团点评技术团队(转)

    https://tech.meituan.com/redux-design-code.html

  8. docker相关命令

    1. 进入docker容器 ① 查看运行的容器:docker ps -a ②  进入容器:docker exec -ti [容器id] bash ③ 退出容器:eixt

  9. eclipse常用快捷键实践积累

    1. [Ctrl + D]:删除一整行 2. 给函数添加注释 [选中函数名]-[Alt + Shift + J].如果需要自定义注释内容可通过[项目]-[属性]-[Java代码样式]-[代码模板]-[ ...

  10. 【软件】chrome设置默认字体

    安装stylish插件 新建样式,加入代码 * { font-family: "Microsoft YaHei", "微软雅黑" !important; }