poj 2417 Discrete Logging ---高次同余第一种类型。babystep_gaint_step
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 2831 | Accepted: 1391 |
Description
B^L == N (mod P)
Input
Output
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
/* 模板题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的更多相关文章
- BSGS算法+逆元 POJ 2417 Discrete Logging
POJ 2417 Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4860 Accept ...
- POJ 2417 Discrete Logging (Baby-Step Giant-Step)
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 2819 Accepted: 1386 ...
- 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 ...
- POJ 2417 Discrete Logging ( Baby step giant step )
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3696 Accepted: 1727 ...
- POJ 2417 Discrete Logging 离散对数
链接:http://poj.org/problem?id=2417 题意: 思路:求离散对数,Baby Step Giant Step算法基本应用. 下面转载自:AekdyCoin [普通Baby S ...
- 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* ...
- POJ 2417 Discrete Logging BSGS
http://poj.org/problem?id=2417 BSGS 大步小步法( baby step giant step ) sqrt( p )的复杂度求出 ( a^x ) % p = b % ...
- POJ 2417 Discrete Logging(离散对数-小步大步算法)
Description Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 ...
- POJ 2417 Discrete Logging
http://www.cnblogs.com/jianglangcaijin/archive/2013/04/26/3045795.html 给p,a,b求a^n==b%p #include<a ...
随机推荐
- 爬虫5:beautifulsoup
灵活方便的网页解析库,处理高效,支持多种解析器,利用它不用编写正则表达式即可方便的实现网页信息的提取 一. BeautifulSoup的几种解析库 解析器 使用方法 优势 劣势 Pyt ...
- 部署LVS-NAT群集
案例环境 LVS调度器作为Web服务器池的网关,LVS两块网卡,分别连接内外网,外网地址172.16.16.172.24,同时也作为整个群集的VIP,内网地址为192.168.7.21-24/24,是 ...
- ps与grep组合命令使用
管道命令 我们在做运维的时候,经常会使用这个命令ps -ef | grep nginx. ps -ef 表示显示所有进程的消息. | 是管道命令.通常需要借助管道命令”|”多个命令的组合,形式如下: ...
- 记录一次因为意外断电造成gitlab(docker容器)重启之后无法访问的问题
容器启动成功,但是处于unhealthy状态,登录界面500. docker logs gitlab 最终错误是 err="opening storage failed: open bloc ...
- QuantLib 金融计算——数学工具之随机数发生器
目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...
- linux下不同颜色文件的性质
绿色文件: 可执行文件,可执行的程序 红色文件:压缩文件或者包文件 蓝色文件:目录 白色文件:一般性文件,如文本文件,配置文件,源码文件等 浅蓝色文件:链接文件,主要是使用ln命令建立的文件 红色闪烁 ...
- CODEVS-新斯诺克
原题地址:新斯诺克 题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄 ...
- docker 运行容器时为容器起别名
docker run --name=mydemo -p -d 2222:80 imagename --name: 指定容器名称 -p:指定容器端口号 -d:指定容器后台运行
- LOJ3069. 「2019 集训队互测 Day 1」整点计数(min_25筛)
题目链接 https://loj.ac/problem/3069 题解 复数真神奇. 一句话题意:令 \(f(x)\) 表示以原点 \((0, 0)\) 为圆心,半径为 \(x\) 的圆上的整点数量, ...
- Linux快速查看某条命令的版本和存放的位置(ls -l `which mvn`)
输入: ls -l `which mvn` 如图: