在这题TLE了一天…T_T

BSGS裸题…不知道为什么一直挂

第二天(也就是今天)换成黄学长博客里的写法就过掉了


题意:解关于$x$的方程:$a^x \equiv b \pmod{p}$,$p$为质数,有多解则输出最小的那个

(和原题里的字母不一样x)

这玩意好像叫离散对数。

首先得注意到$x$的取值只有可能是$0~p-1$,因为费马小定理告诉我们$a^{p-1} \equiv a^{0} \pmod{p}$,这时候出现了循环

不过直接枚举复杂度还是不行的

考虑把$x$写成$x=k*m+i$的形式(这里先不说$m$取多少),原方程变成$a^{km+i} \equiv b \pmod{p}$

移过去:$a^i \equiv b*a^{-km} \pmod{p}$

然后可以先处理出所有可能的$i$(即$i=0,1,...,m-1$)所对应的$a^i$,然后把每个结果和对应的最小的$i$存到map里面

再枚举$k$,根据需要的结果查找所对应的的最小$i$,这里计算$a^{-km}$可以递推

根据费马小定理$1 \equiv a^{p-1} \pmod{p}$两边乘上$a^{-m}$就可以得到$a^{-m} \equiv a^{p-1-m} \pmod{p}$

然后我们可以根据$k$来递推$a^{-km}$

然后来看看怎么取$m$,预处理所有的$a^i$一共是$m$个,丢到map里复杂度也是就是$O(mlogm)$

对于给定的$m$,要枚举$\frac{p}{m}$个$k$,每次也是log的复杂度,总复杂度$O((m+\frac{p}{m})log m)$

所以当$m$取$\sqrt{p}$时复杂度最优,复杂度$O(\sqrt{p}log \sqrt{p})$

实现的地方把map[1]=0写成map[1]=m+1(一个取不到的值)应该也是为了方便后面的判断

#include<cstdio>
#include<cmath>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long lint; map<lint,lint>x; inline lint mul_mod(lint a,lint b,lint p)
{
lint res=a%p*b%p;res=(res%p+p)%p;return res;
} inline lint pow_mod(lint a,lint b,lint p)
{
lint res=1;
for(;b;b>>=1,a=(a*a)%p)if(b&1)res=(res*a)%p;
return res;
} inline lint BSGS(lint a,lint b,lint p)
{
a%=p;x.clear();
if(!a&&!b)return 1;
if(!a)return -1;
lint m=ceil(sqrt(p)),t=1;
x[1]=m+1;
for(register int i=1;i<m;i++)
{
t=mul_mod(t,a,p);
if(!x[t])x[t]=i;
}
lint tmp=pow_mod(a,p-m-1,p),inv=1;
for(register int k=0;k<m;k++)
{
lint i=x[b*inv%p];
if(i)
{
if(i==m+1)i=0;
return k*m+i;
}
inv=mul_mod(inv,tmp,p);
}
return -1;
} int main()
{
//freopen("input.in","r",stdin);
lint res,b,n,p;
while(scanf("%lld%lld%lld",&p,&b,&n)==3)
{
res=BSGS(b,n,p);
if(res==-1)puts("no solution");
else printf("%lld\n",(res%p+p)%p);
}
return 0;
}

如果有说错还请在评论区怼我

[日常摸鱼]poj2417 DiscreteLogging-BSGS算法的更多相关文章

  1. [日常摸鱼]bzoj2038[2009国家集训队]小Z的袜子-莫队算法

    今天来学了下莫队-这题应该就是这个算法的出处了 一篇别人的blog:https://www.cnblogs.com/Paul-Guderian/p/6933799.html 题意:一个序列,$m$次询 ...

  2. [日常摸鱼]Vijos1083小白逛公园-线段树

    题意:单点修改,询问区间最大子段和,$n\leq 5e5$ 考虑分治的方法$O(nlogn)$求一次最大子段和的做法,我们是根据中点分成左右两个区间,那么整个区间的答案要么是左边答案,要么是右边答案, ...

  3. [日常摸鱼]bzoj4802 欧拉函数-PollardRho大整数分解算法

    啊居然要特判,卡了好久QAQ (好像Windows下的rand和Linux下的不一样? QwQ一些东西参考了喵铃的这篇blog:http://www.cnblogs.com/meowww/p/6400 ...

  4. [日常摸鱼]bzoj3122 [Sdoi]2013 随机数生成器

    又是写了一晚上才过的题- 题意:有一个数列$x_n=(ax_{n-1}+b) mod p$,给你$x_1,a,b,p,t$,求最小的$x_i=t$的$i$,可能不存在 一开始很自然的推出了式子$x_n ...

  5. Hash 日常摸鱼笔记

    本篇文章是Hash在信息学竞赛中的应用的学习笔记,分多次更新(已经有很多坑了) 一维递推 首先是Rabin-Karp,对于一个长度为\(m\)的串\(S\) \(f(S)=\sum_{i=1}^{m} ...

  6. [日常摸鱼]HDU1724 Ellipse-自适应Simpson法

    模板题~ QAQ话说Simpson法的原理我还是不太懂-如果有懂的dalao麻烦告诉我~ 题意:每次给一个椭圆的标准方程,求夹在直线$x=l$和$x=r$之间的面积 Simpson法 (好像有时候也被 ...

  7. [日常摸鱼]bzoj1257余数之和

    题意:输入$k,n$,求$\sum_{i=1}^n k \mod i$ $k \mod i=k-i*\lfloor \frac{k}{i} \rfloor $,$n$个$k$直接求和,后面那个东西像比 ...

  8. [日常摸鱼]bzoj1001狼抓兔子-最大流最小割

    题意就是求最小割- 然后我们有这么一个定理(最大流-最小割定理 ): 任何一个网络图的最小割中边的容量之和等于图的最大流. (下面直接简称为最大流和最小割) 证明: 如果最大流>最小割,那把这些 ...

  9. [日常摸鱼]pojKaka's Matrix Travels-拆点+最大费最大流

    方格取数的升级版,每个格子最多取一次. $k=1$的话就是个普及组的dp题,$k=2$就是在之前的基础上多加两维. 然而现在$k$太大了当然就不dp啦 对于$k=1$的情况我们还可以把$(i,j)$向 ...

随机推荐

  1. java开发三年,Java中接口的使用你得知道,不然你凭什么涨薪

    接口概述: 接口是Java语言中的一种引用类型,是方法的"集合",所以接口的内部主要就是定义方法,包含常量,抽象方法(JDK 7及以前),额外增加默认方法和静态方法(JDK 8), ...

  2. bash反弹shell检测

    1.进程 file descriptor 异常检测 检测 file descriptor 是否指向一个socket 以重定向+/dev/tcp Bash反弹Shell攻击方式为例,这类反弹shell的 ...

  3. 这份SpringMVC执行原理笔记,建议做java开发的好好看看,总结的很详细!

    什么是SpringMVC? Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供的web模块,包含了开发Web 应用程 ...

  4. Thrift接口简介

    参考地址:http://roclinux.cn/?p=3316 [thrift是什么] 计算机技术里一款著名的通信框架 – thrift框架 thrift的全名叫做Apache thrift,是一款软 ...

  5. Java基础教程——正则表达式

    正则表达式·Regular Expression 正则表达式就是一个用于匹配字符串的模板,正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别. 主要用到的对象: java.util.rege ...

  6. java多线程--【Foam番茄】

    进程 是系统资源分配的单位 线程 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义.线程是cpu调度和执行的单位 注意:很多多线程是模拟出来的,真正的多线程是指有多 ...

  7. Golang性能分析与优化

    在公司的分享,去除了相关的敏感信息.

  8. gitlab 文件读取+rce复现 CVE202010977

    文件读取实现,首先生成两个project 再任意一个project添加issue,然后描述如下: ![a](/uploads/11111111111111111111111111111111/../. ...

  9. 第三十六章、PyQt输入部件:QAbstractSpinBox派生类QSpinBox、 QDoubleSpinBox、QDateTimeEdit、QDateEdit和QTimeEdit

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 Designer输入部件中的Spin B ...

  10. HTTP请求头和响应头详解【转】

    最近老猿在开始学习爬虫相关的知识,由于老猿以前只做非web的后台应用,发现相关知识太过匮乏,导致学习很困难,为此不得不从一些基础知识恶补开始,对于这些知识,老猿会将网上找到的比较认可的内容直接转发. ...