POJ 2417 Discrete Logging

Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 4860   Accepted: 2211

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
 /*BSGS算法+逆元*/
这个主要是用来解决这个题: A^x=B(mod C)(C是质数),都是整数,已知A、B、C求x。 我在网上看了好多介绍,觉得他们写得都不够碉,我看不懂…于是我也来写一发。 先把x=i*m+j,其中m=ceil(sqrt(C)),(ceil是向上取整)。 这样原式就变为A^(i*m+j)=B(mod C), 再变为A^j=B*A^(-m*i) (mod C), 先循环j=~(C-),把(A^j,j)加入hash表中,这个就是Baby Steps 下面我们要做的是枚举等号右边,从hash表中找看看有没有,有的话就得到了一组i j,x=i*m+j,得到的这个就是正确解。 所以,接下来要解决的就是枚举B*A^(-m*i) (mod C)这一步(这就是Giant Step A^(-m*i)相当于1/(A^(m*i)),里面有除法,在mod里不能直接用除法,这时候我们就要求逆元。 /*百度百科: 若ax≡1 mod f, 则称a关于模f的乘法逆元为x。也可表示为ax≡1(mod f)。
当a与f互素时,a关于模f的乘法逆元有唯一解。如果不互素,则无解。如果f为素数,则从1到f-1的任意数都与f互素,即在1到f-1之间都恰好有一个关于模f的乘法逆元。
*/ 然后我们用超碉的exgcd求逆元,exgcd(扩展欧几里德算法)就是在求AB的最大公约数z的同时,求出整数x和y,使xA+yB=z。算法实现就是gcd加几个语句。
然后我们再来看一下exgcd怎么求逆元:
对xA+yB=z, 变成这样xA = z - yB,取B=C(C就是我们要mod的那个) 推导出 xA % C = z %C 只要 z%C== 时,就可以求出A的逆元x 但用exgcd求完,x可能是负数,还需要这样一下:x=(x%C+C)%C //--exgcd介绍完毕-- 再看我们的题目, exgcd(A^(m*i) , C)=z,当C是质数的时候z肯定为1,这样exgcd求得的x就是逆元了。 因为x就是A^(m*i)的逆元,P/(A^(m*i))=P*x,所以 B*A^(-m*i) = B/(A^(m*i)) = B*x(mod C) 这样我们的式子A^j=B*A^(-m*i) (mod C)的等号右边就有了,就是B*x,就问你怕不怕! 枚举i,求出右边在hash里找,找到了就返回,无敌! /*---------分割线-----------------------*/
#include<cmath>
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
#define mod 100007
#define ll long long
struct hash
{
ll a[mod+],v[mod+];
hash(){memset(a,-,sizeof(a));}
int locate(ll x)
{
ll l=x%mod;
while(a[l]!=x&&a[l]!=-) l=(l+)%mod;
return l;
}
void insert(ll x,int i)
{
ll l=locate(x);
if(a[l]==-)
{
a[l]=x;
v[l]=i;
}
}
int get(ll x)
{
ll l=locate(x);
return (a[l]==x)?v[l]:-;
}
void clear()
{
memset(a,-,sizeof(a));
}
}s;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==)
{
x=;
y=;
return ;
}
exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-a/b*y;
}
int main()
{
ll p,b,n;
while(scanf("%I64d%I64d%I64d",&p,&b,&n)==)
{
s.clear();
ll m=ceil(sqrt(p));
ll t=;
for(int i=;i<m;++i)
{
s.insert(t,i);
t=(t*b)%p;
}
ll d=,ans=-;
ll x,y;
for(int i=;i<m;++i)
{
exgcd(d,p,x,y);
x=((x*n)%p+p)%p;
y=s.get(x);
if(y!=-)
{
ans=i*m+y;
break;
}
d=(d*t)%p;
}
if(ans==-)
printf("no solution\n");
else printf("%I64d\n",ans);
} return ;
}

BSGS算法+逆元 POJ 2417 Discrete Logging的更多相关文章

  1. 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 ...

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

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

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

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

  4. poj 2417 Discrete Logging ---高次同余第一种类型。babystep_gaint_step

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

  5. POJ 2417 Discrete Logging BSGS

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

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

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

  7. POJ 2417 Discrete Logging 离散对数

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

  8. 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* ...

  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. 带你优雅的使用 icon

    前言 本篇文章其实陆陆续续写了快半年,主体部分写好了很久了,但由于种种原因一直没有发布.首先来说说写这篇文章的主要初衷是:在做前端后台项目的时候经常会用到很多 icon 图标,刚开始还好,但随着项目的 ...

  2. 简单漂亮的php验证码函数

    /* *说明:函数功能是生成验证码 * 参数说明:输入 长度,宽度,高度 */ function vcode($_code_length = , $_width = , $_height = ){ $ ...

  3. 338.Counting Bits---位运算---《剑指offer》32

    题目链接:https://leetcode.com/problems/counting-bits/description/ 题目大意:求解从0到num的所有数的二进制表示中所有1的个数. 法一:暴力解 ...

  4. eclipse maven jetty启动修改默认端口

    如何修改eclipse中的maven项目jetty服务器的默认端口那?网上有很多办法,但配置上都没有效果,最后找到了简单.简洁的解决办法,就是在eclipse的jetty启动命令后面加上以下内容 je ...

  5. Apache虚拟主机配置(多个域名访问多个目录)(转)

    Apache虚拟主机配置(多个域名访问多个目录) 为了方便管理虚拟主机,我决定使用一种方法,那就是修改httpd-vhosts.conf文件. 第一步首先要使扩展文件httpd-vhosts.conf ...

  6. MySQL 操作总结

    1. 数据库级别操作 1.1 创建数据库 CREATE DATABASE db1 default charset utf8 collate utf8_general_ci; 1.2 删除数据库 DRO ...

  7. 【转载】移动开发中的上下左右滑动插件jquery.swipe.js

    原文地址http://blog.csdn.net/pvfhv/article/details/3449803/# 源码: (function($) { var old = $.fn.swipe; $. ...

  8. PHP安全编程:register_globals的安全性

    如果你还能记起早期Web应用开发中使用C开发CGI程序的话,一定会对繁琐的表单处理深有体会.当PHP的register_globals配置选项打开时,复杂的原始表单处理不复存在,公用变量会自动建立.它 ...

  9. SICP第三章题解

    目录 SICP第三章题解 ex3-17 ex3-18 ex3-19 队列 ex3-21 ex3-22 ex3-24 ex3-25 3.4 并发:时间是一个本质问题 ex3-38 3.4.2 控制并发的 ...

  10. anaconda不错的