题意

给定 $a,b$ 和模数 $p$,求整数 $x$ 满足 $a^x \equiv  b(mod \ p)$,不保证 $a,p$ 互质。

(好像是权限题,可见洛谷P4195

分析

之前讲过,可以通过设置 $x = km - r$ 而非 $x = km + r$ 避免求逆元,但是需要逆元存在,$a, p$ 互质的条件保证了这一点。

如果 $a, p$ 不互质怎么办呢?

我们想办法让他们变得互质。

具体地,设 $d_1 = gcd(a, p)$,如果 $d_1 \nmid b$,则原方程无解。否则我们把方程同时除以 $d_1$,得到

$$\frac{a}{d_1}\cdot a^{x-1} \equiv \frac{b}{d_1} \ mod (\frac{p}{d_1})$$

如果 $a$ 和 $\frac{p}{d_1}$ 仍不互质就再除,设 $d_2=gcd(a, \frac{p}{d_1})$。如果 $d2 \nmid \frac{b}{d_1}$,则方程无解;否则同时除以 $d_2$ 得到

$$\frac{a^2}{d_1d_2}\cdot a^{x-2} \equiv \frac{b}{d_1d_2} \ mod(\frac{p}{d_1d_2})$$

这样不停地判断下去,直到 $a \perp \frac{p}{d_1d_2...d_k}$。

记 $D = \prod_{i=1}^kd_i$,于是方程就变成了这样:

$$\frac{a^k}{D}\cdot a^{x-k} \equiv \frac{b}{D} \ mod(\frac{p}{D})$$

由于 $a \perp \frac{p}{D}$,于是推出 $\frac{a^k}{D} \perp \frac{p}{D}$。这样 $\frac{a^k}{D}$ 就有逆元了,于是把它丢到方程的右边,就是一个普通的BSGS问题了,于是求解 $x-k$ 再加上 $k$ 就是原方程的解。

$\frac{a^k}{D}$ 可能很大,事实上可以随手模 $\frac{p}{D}$(显然)。

注意,不排除解小于等于 $k$,所以在消因子之前做 $O(k)$ 枚举,直接验证 $a^i \equiv b\ mod(p)$,就能避免这种情况。

这个复杂度已经有点玄学了,普通的BSGS的复杂度为 $O(\sqrt p logp)$。洛谷上100组,$a, b, p \leq 1e9$,map不开O2优化会超时,需要开O2优化或者使用unordered_map。

代码

#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll; ll gcd(ll a, ll b)
{
return b ? gcd(b, a%b) : a;
} ll qpow(ll a, ll b, ll p)
{
a = a % p;
ll ret = ;
while(b)
{
if(b&) ret = ret * a % p;
a = a * a %p;
b >>= ;
}
return ret % p;
} ll extend_bsgs(ll a, ll b, ll p) //a^x=b(mod p),a,p不一定互质,不存在返回-1
{
ll _a = a, _b = b, _p = p;
a %= p; b %= p;
if (a == )
return b > ? - : b == && p > ;
ll g, cnt = , q = ;
while ((g = gcd(a, p)) != ) {
if (b == q) return cnt;
if (b % g) return -;
++cnt;
b /= g;
p /= g;
q = a/g*q%p; //可以随手取模
} ll tmp = ;
for(int i = ;i <= cnt;i++) //枚举小于等于cnt的(好像也不是必须的
{
if(tmp % _p == _b) return i;
tmp = tmp * _a % _p;
} map<ll, ll> x;
ll m = sqrt(p);
for (ll i = , t = b*a%p; i <= m; ++i, t = t*a%p)
x[t] = i;
for (ll i = m, t = qpow(a, m, p); i-m < p-; i += m)
if (q = q*t%p, x.count(q))
return i-x[q]+cnt;
return -;
} int main()
{
ll a, p, b;
while (scanf("%lld %lld %lld", &a, &p, &b), p) {
ll ans = extend_bsgs(a, b, p);
if (ans == -)
puts("No Solution");
else
printf("%lld\n", ans);
}
return ;
}

参考链接:

1. 大步小步算法(BSGS)及扩展  & bzoj2480

2. OI WIKI——BSGS算法

bzoj 2480——扩展BSGS的更多相关文章

  1. bzoj 3283 扩展BSGS + 快速阶乘

    T2  扩展BSGS T3 快速阶乘 给定整数n,质数p和正整数c,求整数s和b,满足n! / pb = s mod pc 考虑每次取出floor(n/p)个p因子,然后将问题转化为子问题. /*** ...

  2. BZOJ 2480 && 3239 && 2995 高次不定方程(高次同余方程)

    链接 BZOJ 2480 虽然是个三倍经验题(2333),但是只有上面这道(BZOJ2480)有 p = 1 的加强数据,推荐大家做这道. 题解 这是一道BSGS(Baby Step Giant St ...

  3. poj 3243 Clever Y && 1467: Pku3243 clever Y【扩展BSGS】

    扩展BSGS的板子 对于gcd(a,p)>1的情况 即扩展BSGS 把式子变成等式的形式: \( a^x+yp=b \) 设 \( g=gcd(a,p) \) 那么两边同时除以g就会变成: \( ...

  4. BSGS与扩展BSGS

    BSGS \(BSGS\)算法又称大步小步\((Baby-Step-Giant-Step)\)算法 \(BSGS\)算法主要用于解以下同余方程 \[A^x\equiv B(mod\ p)\]其中\(( ...

  5. BSGS&扩展BSGS

    BSGS 给定\(a,b,p\),求\(x\)使得\(a^x\equiv b \pmod p\),或者说明不存在\(x\) 只能求\(\gcd(a,p)=1\)的情况 有一个结论:如果有解则必然存在\ ...

  6. POJ 3243 Clever Y 扩展BSGS

    http://poj.org/problem?id=3243 这道题的输入数据输入后需要将a和b都%p https://blog.csdn.net/zzkksunboy/article/details ...

  7. BSGS和扩展BSGS

    BSGS: 求合法的\(x\)使得\(a ^ x \quad mod \quad p = b\) 先暴力预处理出\(a^0,a^1,a^2.....a^{\sqrt{p}}\) 然后把这些都存在map ...

  8. 扩展BSGS求解离散对数问题

    扩展BSGS用于求解axΞb mod(n) 同余方程中gcd(a,n)≠1的情况 基本思路,将原方程转化为a与n互质的情况后再套用普通的BSGS求解即可 const int maxint=((1< ...

  9. bzoj 1467: Pku3243 clever Y 扩展BSGS

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

随机推荐

  1. 【面试】IP数据报格式分析

    (除选项外的报头区总共20个字节) 1)版本:IPV4/IPV6 2)头长度:报头区长度,用于计算数据区的开始位置,比如头长度为6,代表报头区长度为6*4个字节,头长度的单位为4字节,所以报头区长度不 ...

  2. Kafka工具教程 - Apache Kafka中的2个重要工具

    1.目标 - 卡夫卡工具 在我们上一期的Kafka教程中,我们讨论了Kafka Workflow.今天,我们将讨论Kafka Tool.首先,我们将看到卡夫卡的意义.此外,我们将了解两个Kafka工具 ...

  3. kubernetes 实践三:使用kubeadm安装k8s1.16.0

    环境版本说明: 三台vmware虚拟机,系统版本CentOS7.6. Kubernetes 1.16.0,当前最新版. flannel v0.11 docker 18.09 使用kubeadm可以简单 ...

  4. 接口与DRF的安装

    接口 # 接口:url链接,通过向链接发送不同的类型请求与参数得到相应的响应数据​# 1.在视图层书写处理请求的 视图函数# 2.在路由层为视图函数配置 url链接 => 产生接口# 3.前台通 ...

  5. CCF 2016-04-2 俄罗斯方块

    CCF 2016-04-2 俄罗斯方块 题目 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者 ...

  6. C盘清理、C盘瘦身、省出30G

    三招C盘瘦身30G,清理win10系统中虚占C盘空间的三大祸害 1.对C盘进行“磁盘清理” C盘右键->属性->磁盘清理->清理系统文件->勾选“windows更新清理”-&g ...

  7. QSDK与OPENWRT区别

    QSDK与OPENWRT区别 来源 https://www.jianshu.com/p/178ae18b2570 QSDK是一种在openwrt的基础上,加入了高通atheros芯片相关资料的一种环境 ...

  8. idea: unable to import maven project

    新搭建的maven环境,使用idea创建maven项目时,一直提示 unable to import maven project,百度良久未解决 有说关闭防火前的,亲测无效,后看到说是maven-3. ...

  9. css设置全局变量和局部变量

    在我们使用less或者sass时常常会使用到局部变量和全局变量,其实在我们使用css做开发时也可以定义全局变量和局部 变量来简化我们的开发效率,很简单也很实用:1.设置全局变量只需要在我们的根引用的c ...

  10. SQL*Plus 与数据库的交互(SQL*Plus时什么)

    Oracle 的 SQL*Plus 是与数据库进行交互的客户端工具,在 SQL*Plus中,可以运行 SQL*Plus 命令与 SQL*Plus 语句.   SQL*Plus 时一个基于 C/S 两层 ...