POJ 2417 Discrete Logging ( Baby step giant step )
| Time Limit: 5000MS | Memory Limit: 65536K | |
| Total Submissions: 3696 | Accepted: 1727 |
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
Hint
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
题意要求解一个 k^D = n ( mod p ) 的一个最小D
一开始也不会解 。
在网上看了一下,原来是用到一个 Baby step giant step 的算法 。
先要把 D 分解 , D = i * m + j ( m = ceil( sqrt (p - 1 ) ) )
原式 : k^D = n ( mod p )
-> k^i^m * k^j = n (mod p )
-> k^j = n * ( k ^(-m)^ i ) ( mod p )
根据题目给的 Hint ( 费马小定理 )可以求出 k^m 的逆元 .
然后枚举 i , 查找是否存在 k^j 与 n * ( k ^(-m)^i ) 相等
所以预处理 k^j ( mod p ) 排序以后 , 就可以进行二分查找了 (复杂度降为log(m))。
加上枚举 , 那么总复杂度就是 m*log(m) .
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL ;
const int N = ; struct B
{
LL num , id ;
bool operator < ( const B &a ) const{
if( num != a.num ) return num < a.num;
else return id < a.id ;
}
}baby[N]; LL n , k , p ;
int tot ; LL quick_mod( LL a , LL b ,LL mod )
{
LL res = ;
while( b )
{
if( b & ) res = res * a % mod ;
a = a * a % mod ;
b >>= ;
}
return res ;
}
int find( LL n )
{
int l = , r = tot - ;
while( l <= r ){
int m = (l + r) >> ;
if( baby[m].num == n){
return baby[m].id;
}
else if( baby[m].num < n )
l = m + ;
else
r = m - ;
}
return -;
}
void run()
{
int m = (int)ceil(sqrt((double)(p-)));
baby[].num = , baby[].id = ;
for( int i = ; i < m ; ++i ){
baby[i].id = i ;
baby[i].num = baby[i-].num * k % p ; // k^j
}
sort( baby , baby + m );
tot = ;
for( int i = ; i < m ; ++i ){
if( baby[tot-].num != baby[i].num ) baby[tot++] = baby[i];
} LL bm = quick_mod( k , p - - m , p ) ; // k^(-m) ;
LL temp = n ; for( int j = ; j < m ; ++j ){
// k^(-m)^j
int pos = find( temp );
if( pos != - ){
printf("%d\n" , ( m * j + pos ) );
return ;
}
temp = temp * bm % p ;
}
puts("no solution");
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
while( ~scanf("%lld%lld%lld",&p,&k,&n) ) run();
}
POJ 2417 Discrete Logging ( Baby step giant step )的更多相关文章
- BSGS算法+逆元 POJ 2417 Discrete Logging
POJ 2417 Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4860 Accept ...
- POJ 2417 Discrete Logging 离散对数
链接:http://poj.org/problem?id=2417 题意: 思路:求离散对数,Baby Step Giant Step算法基本应用. 下面转载自:AekdyCoin [普通Baby S ...
- 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(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 ---高次同余第一种类型。babystep_gaint_step
Discrete Logging Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 2831 Accepted: 1391 ...
- 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(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(离散对数-小步大步算法)
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 ...
随机推荐
- [转载]Redux原理(一):Store实现分析
写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何管理stat ...
- 17-正交矩阵和Gram-Schmidt正交化
一.视频链接 1)正交矩阵 定义:如果一个矩阵,其转置与自身的乘积等于单位向量,那么该矩阵就是正交矩阵,该矩阵一般用Q来表示,即$Q^TQ=QQ^T=I$,也就是$Q^T=Q^{-1}$,即转置=逆 ...
- 北京太速科技有限公司 layout 事业部
涵盖领域设计能力 ·通信板卡:PCI/PCIE/CPCI/VPX/光通信/无线通信/射频雷达/显卡 1.最小线宽:2MIL·主板服务器:电脑主板/交换机/服 ...
- foreach与正常for循环效率对比
foreach foreach编译成字节码之后,使用的是迭代器实现的. foreach特点: 无须获取容器大小 需要创建额外的迭代器变量 遍历期间得到的是对象,没有索引位置信息,因此不能进行赋值操作. ...
- python socket 的理解(1)
前言 socket的用法简单,但里面的概念有点模糊,记录自己本人的一点理解. socket层结构图 注意,从此图中看出socket处于tcp和应用层之间.那么它代表啥意思呢?简明的说,数据的传输都是底 ...
- Nginx配置参数详解参考示例
user nobody; worker_processes 2; events{ worker_connections 1024; } http{ #设置默认类型为二进制流 default_type ...
- ASIO
{ 编译ASIO库时,出现编译警告, "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n& ...
- tomcat启动一闪而过处理
进入tomcat安装目录(解压目录)下的bin目录,比如D:\Tomcat1\apache-tomcat-7.0.810\bin,打开startup.bat文件,在最上面加上下面两句: SET JAV ...
- Linux0.11内核源码——内核态进程切换的改进
本来想自己写的,但是发现了一篇十分优秀的博客 https://www.cnblogs.com/tradoff/p/5734582.html system_call的源码解析:https://blog. ...
- Activity 启动模式总结
Activity 启动模式: 1. standard: 默认启动模式,每次启动一个Activity都会重新创建一个实例: 2. singleTop: 栈顶复用模式,新Activity位于任务栈的栈顶, ...