http://poj.org/problem?id=2417

A^x = B(mod C),已知A,B。C。求x。

这里C是素数,能够用普通的baby_step。

在寻找最小的x的过程中,将x设为i*M+j。从而原始变为A^M^i * A^j = B(mod C),D = A^M,那么D^i * A^j = B(mod C ),

预先将A^j存入hash表中,然后枚举i(0~M-1),依据扩展欧几里得求出A^j。再去hash表中查找对应的j,那么x = i*M+j。

确定x是否有解,就是在循环i的时候推断对应A^j是否有解。并且最小的解x一定在(0~C-1),由于gcd(D^i,C) = 1.

假设(0~C-1)无解,那么一定无解。

由于A^x%C(C是素数)有循环节。A^x%C = A^(x%phi[c])%C,循环节的长度为phi(C),即C-1,x >= C以后開始新一轮的循环,因此(0~C-1)内无解的话。一定无解。



#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0) using namespace std;
const int maxn = 499991; bool hash[maxn+10];
int idx[maxn+10];
LL val[maxn+10];
//插入哈希表
void insert(int id, LL vv)
{
int v = vv % maxn;
while(hash[v] && val[v] != vv)
{
v++;
if(v == maxn)
v -= maxn;
}
if(!hash[v])
{
hash[v] = true;
idx[v] = id;
val[v] = vv;
}
}
//查找vv相应的jj,A^jj = vv
int found(LL vv)
{
int v = vv%maxn;
while(hash[v] && val[v] != vv)
{
v++;
if(v == maxn)
v -= maxn;
}
if(hash[v] == false)
return -1;
return idx[v];
} void extend_gcd(LL a, LL b, LL &x, LL &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
extend_gcd(b,a%b,x,y);
LL t = x;
x = y;
y = t-a/b*y;
}
/*
A^x = B(mod C)
令x = i*M+j, 当中M = ceil(sqrt(C*1.0)),(0 <= i,j < M)
那么原式变为A^M^i*A^j = B(mod c)
先枚举j(0~M-1),将A^j%C存入hash表中
令D = A^M%C,X = A^j,那么D^i*X = B(mod C)
枚举i(0~M-1)求得D^i设为DD。DD*X = B(mod C)
DD,C已知,由于C是素数,gcd(DD,C) = 1,依据扩展欧几里得知在[0,C-1]内有唯一一个解X。
然后在hash表中查找X相应的jj。即A^jj = X。 那么x = i*M+jj,若找不到jj无解。
*/
LL baby_step(LL A, LL B, LL C)
{
memset(hash,false,sizeof(hash));
memset(idx,-1,sizeof(idx));
memset(val,-1,sizeof(val)); LL M = ceil(sqrt(C*1.0));
//将A^j存入hash表中
LL D = 1;
for(int j = 0; j < M; j++)
{
insert(j,D);
D = D*A%C;
}
//D = A^M%C,res = D^i,求方程res*X = B(mod C)中的X,去找X相应的jj,那么x=i*M+jj.
LL res = 1,x,y;
for(int i = 0; i < M; i++)
{
extend_gcd(res,C,x,y);
x = x*B;
x = (x%C+C)%C;
int jj = found(x);
if(jj != -1)
{
return (LL)i*M+jj;
}
res = res*D%C;
}
return -1;
} int main()
{
LL A,B,C;
while(~scanf("%lld %lld %lld",&C,&A,&B))
{
LL res = baby_step(A,B,C);
if(res == -1)
printf("no solution\n");
else
printf("%lld\n",res);
}
return 0;
}

poj 2417 Discrete Logging(A^x=B(mod c),普通baby_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 ---高次同余第一种类型。babystep_gaint_step

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

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

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

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

  6. POJ 2417 Discrete Logging 离散对数

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

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

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

  8. POJ 2417 Discrete Logging BSGS

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

  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. tomcat压缩优化和缓存策略

    tomcat压缩内容 tomcat的压缩优化就是将返回的html页面等内容经过压缩,压缩成gzip格式之后.发送给浏览器,浏览器在本地解压缩的过程. 对于页面量信息大或者带宽小的情况下用压缩方式还是蛮 ...

  2. 每天一个JavaScript实例-html5拖拽

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. malloc一次性最大能申请多大内存空间

    受用户态内存地址空间的限制.64 位系统下分配几个 T 不成问题. 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:zz matrix链接:http://www.zhihu. ...

  4. Instruments的使用 逻辑查错,内存泄漏分析等工具集

    原创文章,转载请注明 XCode 开发后期,要对代码进行改进和优化,查内存泄漏是其中一项重要工作,今天下午偷了点时间,把前段时间的代码稍微整理了一下,顺带用了下这个工具,还真发现了些问题.这里记录一下 ...

  5. [WPF]DataGrid C#添加右键弹出选择菜单

    private void dataGrid_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { ContextMenu cont ...

  6. 矩形旋转碰撞,OBB方向包围盒算法实现

    怎样进行2D旋转矩形的碰撞检測.能够使用一种叫OBB的检測算法(Oriented bounding box)方向包围盒.这个算法是基于SAT(Separating Axis Theorem)分离轴定律 ...

  7. swift 笔记 (十八) —— 扩展

    扩展 扩展能够让我们给一个已有的类.结构体.枚举等类型加入�新功能,包含属性和方法,甚至是构造器,下标,支持协议等等... 甚至是我们拿不到源码的类.结构体.枚举,我们依旧能够给它加扩展... 看到这 ...

  8. 添加xml文件编辑语法提示

    找到Struts的lib目录 找到struts2-core-文件并解压开 这个struts.dtd文件才是我们需要添加的文件 双击XML Catalog 点击ADD Key中复制粘贴D:\web\st ...

  9. hadoop-1.1.2 在Windows环境下的部署

    1:先安装Cygwin 参考http://blog.csdn.net/wind520/article/details/9223003 2:下载 3:解压在C:\cygwin\hadoop1 4:配置 ...

  10. 同步特定源代码到 omni_rom源代码目录里面

    #!/bin/bash base_path="/Volumes/Android/omnirom_5.0" #此目录是我存放源代码的目录 xiaomi_device="de ...