一.引入:

若存在一个式子a^b ≡ c (mod p) (p ≡ 1000000007,且0<a,b,c<p)

   已知a,b,求c.

     这不就是快速幂嘛!

  已知a,c,求b.

    这就是我们需要研究的问题!用到了BSGS!

题目链接:poj 2417 bsgs

二.概念

BSGS:

又名大步小步算法.具体的我也不清楚啦~

那么发明来做什么事情呢?

如上所述:

  就是用来求解a^x ≡ b (mod p)这样的式子

    PS:已知a,b,p

        求最小x

三.做法

首先,我们将x用i*m-j来表示,其中我们的m=seil(sqrt(p)),(seil为向上取整)

然后我们用i*m-j代替掉x,所以原式就变成了这个样子

        a^(i * m-j) ≡ b (mod p)

又因为a^(i * m-j)  =>  a^(i * m)/a^j

所以原式又变了模样:

        a^(i * m)/a^j ≡ b (mod p)

又因为在"≡"(同余号)的两侧同时乘以一个相同的数依旧是成立的,如果不明白可以手动模拟一下,

给出个栗子~

  3 ≡ 10 (mod 7),当两边同乘以5时式子变成: 15 ≡ 50 (mod 7)

  因为15%7==1&&50%7==1,所以原式依旧成立

所以将式子两边同时乘以a^j

那么式子就又发生了改变:

        a^(i * m) ≡ b * a^j (mod p)

    = (a^m)^i ≡ b * a^j (mod p)

所以问题就简单多了!

因为a^m是常数,b是常数,p也是常数,所以只有 i 跟 j 是未知的,暴力枚举!

但是有一点是我们不能够忘记的:

m的取值范围:1 —— p(p是当b==0时),所以

首先将 j 从1 到 p-1 进行枚举一遍,求出b * a^j 的值丢到hash(大佬是用map做的)里面咯(讲真hash不会用...怪我咯?)

  思路是这样的:(其实就是hash啦~)

        (b*a^j)%p(如果p太小换成另外一个比较大的质数)作为下标,里面存着当前计算出来的数,以及当前的 j (可以用vector~)

然后,枚举 j ,我们大可以设a^m==c

将 i 从 1 到p-1枚举一遍,如果求出的数在hash里面找到了,则说明当前的数就是 i (能够成立的) 最小值,跳出循环,用当前的i,以及记录下来的 j 计算对应的 i 求出 x

则x就是最小的解

C++代码实现:

(map方法:)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath> using namespace std;
typedef long long LL; LL a,b,c;
map<LL,LL> mp; LL qsm(LL m)
{
LL n = a; if(m == ) return ; LL t = qsm(m/); t = 1LL*t*t%c;
if(m&) t = 1LL*t*n%c; return t;
} int main()
{
//a^im=b*a^j(mod c)
while (scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
{
mp.clear(); //清空
if (a%c==) //判断a,c 是否互质,因为c 是质数,所以直接判断是否整除即可
{
printf("no solution\n");
continue;
}
LL m=ceil(sqrt(c));
LL ans;
for (LL j=; j<=m; j++)
{
if (j==)
{
//当j=0时,a^j=1, b*a^j=b
ans=b%c;
mp[ans]=j;
continue;
}
ans=(ans*a)%c;
//括号里的ans指a^(j-1)*b,(a^(j-1)*b)*a=(a^j)*b
mp[ans]=j;//在((a^j)*b)%c的位置记录下j
}
LL t=qsm(m);//t=a^m
ans=;
bool p=false;
for (LL i=; i<=m; i++)
{
ans=(ans*t)%c;//括号里的ans指的是((a^m)^(i-1))*(a^m)=(a^m)^i=a^(im)
if (mp[ans])
{
LL t=i*m-mp[ans];//t=x,因为我们设的x=i*m-j
printf("%lld\n",t);
p=true;
break;
}
}
if (!p)
printf("no solution\n");
}
}

End.

BSGS ! x的更多相关文章

  1. 【POJ 3243】Clever Y 拓展BSGS

    调了一周,我真制杖,,, 各种初始化没有设为1,,,我当时到底在想什么??? 拓展BSGS,这是zky学长讲课的课件截屏: 是不是简单易懂.PS:聪哥说“拓展BSGS是偏题,省选不会考,信我没错”,那 ...

  2. 【codevs 1565】【SDOI 2011】计算器 快速幂+拓展欧几里得+BSGS算法

    BSGS算法是meet in the middle思想的一种应用,参考Yveh的博客我学会了BSGS的模版和hash表模板,,, 现在才会hash是不是太弱了,,, #include<cmath ...

  3. 【BZOJ-3122】随机数生成器 BSGS

    3122: [Sdoi2013]随机数生成器 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1362  Solved: 531[Submit][Sta ...

  4. BSGS[bzoj2242][bzoj3122]

    数论题. 操作一:直接快速幂就好了. 操作二:我用了exgcd,shy和lyz都喜欢欧拉函数...QAQ最后这块还写错了. 对于ax+by=gcd(a,b)的形式,我们可以把他们变成y'x+p'y=1 ...

  5. 【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS

    Description 你被要求设计一个计算器完成以下三项任务: 1.给定y,z,p,计算Y^Z Mod P 的值: 2.给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数: 3.给 ...

  6. BZOJ-2242 计算器 快速幂+拓展欧几里得+BSGS(数论三合一)

    污污污污 2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2312 Solved: 917 [Submit][S ...

  7. bzoj 1467: Pku3243 clever Y 扩展BSGS

    1467: Pku3243 clever Y Time Limit: 4 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 小 ...

  8. BSGS模版 a^x=b ( mod c)

    kuangbin的BSGS: c为素数: #define MOD 76543 int hs[MOD],head[MOD],next[MOD],id[MOD],top; void insert(int ...

  9. bzoj 2242: [SDOI2011]计算器 BSGS+快速幂+扩展欧几里德

    2242: [SDOI2011]计算器 Time Limit: 10 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 你被 ...

  10. 【poj3358】消因子+BSGS 或 消因子+欧拉定理 两种方法

    题意:给你一个分数,求它在二进制下的循环节的长度,还有第一个循环节从哪一位开始. For example, x = 1/10 = 0.0001100110011(00110011)w and 0001 ...

随机推荐

  1. SAS学习笔记31 SAS随机分组方法及实现

    随机分组方法包括: 简单随机化(simple randomization) 区组随机化(block randomization) 分层随机化(stratified randomization) 分层区 ...

  2. c++/c在两个文件公用一个变量

    在一个cpp文件定义一个文件 在另一个文件extern+定义

  3. 一个因MySQL大小写敏感导致的问题

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 00 MYSQL对大小写敏感 见字如面,见标题知内容.你有遇到过因为MYSQL对大小写敏感而被坑的体验吗? 之前看过阿里巴 ...

  4. mysql cmd命令行 创建数据库 表 基础语句

    一.连接MYSQL 格式: mysql -h主机地址 -u用户名 -p用户密码 1. 连接到本机上的MYSQL. 首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u roo ...

  5. 函数实现计算等差数列的第n项

    等差数列的第n项 描述 等差数列是指从第二项起,每一项与它的前一项的差等于同一个常数的一种数列,这个常数叫做等差数列的公差.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬ ...

  6. 从ABAP Netweaver的SICF到SAP Kyma的Lambda Function

    ABAP Netweaver里的事务码SICF是Jerry做原型开发时非常喜欢使用的一个工具:但凡遇到需要把ABAP系统里的资源以服务的方式暴露出来的场景,Jerry都喜欢在SICF里创建一个服务节点 ...

  7. nginx增加新模块

    以gunzip这个模块为例,讲述一下,在nginx中如何安装新的模块 1.首先查看nginx已经安装了哪些模块. nginx –V 2.发现没有gunzip模块,安装 进入nginx的安装目录中,不是 ...

  8. MySQL主从复制以及在本地环境搭建

    MySQL主从复制原理: master(主服务器),slave(从服务器) MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事binary log ...

  9. 13 Windows编程——系统内置窗口子类型之静态子窗口

    静态子窗口类型 wndclass:static 源码 #include<Windows.h> #include<Windowsx.h> HINSTANCE G_h; LRESU ...

  10. Nginx 的关键组件的介绍

    本文章主要介绍Nginx本身功能,不依赖第三方的任何模块.介绍常用的组件功能:反向代理.负载均衡.Http服务器.正向代理 反向代理(Reverse Proxy): 什么是反向代理呢?本人最直接的理解 ...