在这题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. vue中插值表达式中时间转换yyyy-MM-dd HH:mm:ss

    vue插值表达式中将时间转换两种方式:一.定义方法 <div id="app">当前实时时间:{{dateFormat(date)}}</div> //时间 ...

  2. Lombok之@Builder注解

    Lombok之@Builder注解 前言 Lombok大家都知道,在使用POJO过程中,它给我们带来了很多便利,省下大量写get.set方法.构造器.equal.toString方法的时间.除此之外, ...

  3. objetive-C中属性变量和成员变量

    属性变量 @property和@synthesize可以自动生成某个类成员变量的存取方法. readwrite:这个属性是默认的情况,会自动生成存取器 assign:这个属性一般用来处理基础类型,比如 ...

  4. Vue最简单的实现网页Live2D看板娘

    Live2D看板娘 前言 二.使用步骤 1.引入 2.设置样式 结尾(后续更新更强的配置看板娘~) 前言 最近想给自己的网页添点新花样,然后就想到了别人的网站都有一些看板娘的玩意儿,看着很舒服,鉴于自 ...

  5. 电脑adb命令给智能电视安装APK

    配置环境 1.电脑需要配置好adb系统环境 具体操作较复杂,请自行百度. 2.电视打开adb命令 在电视的关于界面通过遥控器「上上下下左右左右」进入工厂模式,在「高级设置」-「其他」中的「adb开关」 ...

  6. [配置]01.IntelliJ IDEA代码格式化与Eclipse保持风格一致

  7. 聊聊ReentrantLock实现原理

    ReentrantLock 是常用的锁,相对于Synchronized ,lock锁更人性化,阅读性更强 从LOCK切入 考虑下面的场景如果有A,B线程,同时去执行lock.lock(Lock loc ...

  8. Java基础教程——抽象类

    抽象类 抽象类是介于普通类(class)和接口(interface)之间的一种特殊类. 接口的方法都不实现,类的方法都必须实现,抽象类里的方法可以实现,可以不实现. Java 8之后接口中可以实现方法 ...

  9. Beta冲刺随笔——Day_Ten

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 团队进行Beta冲刺 作业正文 正文 其他参考文献 无 今日事今日毕 林涛: ...

  10. [oBIX包使用教程] 使用 Python 通过 oBIX 协议访问 Niagara 数据

    oBIX 全称是 Open Building Information Exchange,它是基于 RESTful Web Service 的接口的标准,用于构建控制系统.oBIX是在专为楼宇自动化设计 ...