当前快看:(ex)BSGS/(扩展)大步小步算法 学习笔记
(ex)BSGS/(扩展)大步小步算法 学习笔记
在即将暂时退役之际杀掉了P4195的毒瘤模板题,于是来写篇学习笔记。
(资料图片仅供参考)
谨此为我初中三年摆烂的OI生涯画上一个句号。(距离中考还有20天!)
BSGS
link
求\(a^x\equiv b\pmod p\)的非负整数解,其中\(a, p\)互质。
算法思路
我们不妨令\(t=\lceil{\sqrt{p}\rceil}\),\(j\lt t\),\(i\leq t\)
原式转化为\(a^{it-j} \equiv b \pmod p\)
即 \(\left(a^t\right)^i\equiv b\cdot a^j \pmod p\)
于是我们可以这么在\(\Theta\left(\sqrt{n}\right)\)(不考虑hash表)内求出解:
枚举\(j \in [0, t)\),求出所有的\(b\cdot a^j \mod p\),用hash表记录下来
枚举\(i \in [0, t]\),求出所有的\(\left(a^t\right)^i \mod p\),在hash表中查找是否有对应的\(j\)值
需要注意的是,当\(a^t \mod p=0\)时,若\(b=0\),则解为\(x=1\);否则无解。
正确性讨论
由Euler定理,我们有\(a^{\varphi\left(p\right)}\equiv 1\pmod p\),其中\(\varphi\left(x\right)\)为Euler函数。
也就是说,\(\mod p\)意义下,\(a^x\mod p\)在\(x=n\cdot\varphi\left(p\right)\)(\(n\)遍历非负整数)后循环。
我们知道对于任意整数\(x \gt 1\),\(x>\varphi\left(x\right)\),而我们取的\(it-j\)可以遍历\([0, x]\),因此能够取到\(a^x \mod p\)的一切情况,故一定不会漏解。
代码实现
#include using namespace std;#define int long longint qpow(int a, int n, int p) { a%=p; int res=1; while (n) { if (n&1) res=res*a%p; a=a*a%p; n>>=1; } return res;}signed bsgs(int a, int b, int p) { b%=p; int t=sqrt(p)+1; unordered_map hash; hash.clear(); for (int j=0; j=0 && i*t-j>=0) return i*t-j; } return -1;}signed main() { int a, b, p; cin>>p>>a>>b; int res=bsgs(a,b,p); if (res==-1) puts("no solution"); else cout<
这份代码是可以通过P3846的。我们可以考虑对它进行优化。
我们发现枚举\(a^j\)和\(\left(a^t\right)^i\)的时候,\(i, j\)是递增的,于是我们可以直接用一个变量来维护\(a^j\)和\(\left(a^t\right)^i\)。
另外,用unordered_map
来实现hash表似乎会快一些。
inline int bsgs(int a, int b, int p) { int t=(int)(sqrt(p))+1; unordered_map h; h.clear(); int powa=1; for (reg int j=0; j=0 && i*t-j>=0) return i*t-j; powa=powa*a%p; } return -1;}
为exBSGS进行修改
我们现在来考虑\(ka^x\equiv b\pmod p\)(\(a, p\)互质,\(k\)为正整数)的式子,我们可以同样地将它们变形为
\[k\cdot \left(a^t\right)^i\equiv b\cdot a^j \pmod p\]于是稍微修改一下上述代码就可以了。
inline int bsgs(int a, int b, int k, int p) { int t=(int)(sqrt(p))+1; unordered_map h; h.clear(); int powa=1; for (reg int j=0; j=0 && i*t-j>=0) return i*t-j; powa=powa*a%p; } return -1;}
exBSGS
link
求\(a^x\equiv b\pmod p\)的非负整数解,其中\(a, p\)未必互质。
算法思路
考虑利用同余式的约化性质,转换成朴素的BSGS
来求解。
我们有如下同余式的约化性质:若\(a\equiv b\pmod p\),\(d\mid a,d \mid b\),则
\(\frac{a}{d}\equiv\frac{b}{d}\pmod {\frac{p}{\gcd(d,p)}}\)
我们回到\(a^x\equiv b\pmod p\),令\(d_1=\gcd(a,p)\),当\(d_1 \mid b\),我们可以变形为\(\frac{a}{d_1}\cdot a^{x-1}\equiv \frac{b}{d_1} \pmod {\frac{p}{d_1}}\)(若\(d_1 \nmid b\),立刻得出无解)若\(a,\frac{p}{d_1}\)仍不互质,我们可以继续令\(d_2=\gcd(a,\frac{p}{d_1})\),\(\cdots\),直到\(a,\frac{p}{d_1d_2\cdots d_k}\)互质为止。
我们设一共进行了\(k\)次约化,\(D=d_1d_2\cdots d_k\)(此时\(a\),\(\frac{p}{D}\)互质),原式可变形为
\(\frac{a^k}{D}\cdot a^{x-k} \equiv \frac{b}{D} \pmod {\frac{p}{D}}\)
我们令\(k=\frac{a^k}{D}, X=x-k, B=\frac{b}{D}, P=\frac{p}{D}\),即
\(ka^X\equiv B \pmod P\)
于是可以利用修改后的BSGS
算法来求解。
注意求解之后得到\(X=x-k\),故\(x=X+k\)。
Trick
\(\frac{a^k}{D}=\frac{a}{d_1}\frac{a}{d_2}\cdots\frac{a}{d_k}\),于是可以在每一个循环内单独计算。
用cout<<"\n"
似乎会比用cout<
可以预先将b%=p, a%=p
,若取模过后\(b==1\)或者\(p==1\),那么显然\(x=0\)为解。
我们记\(D_k=\frac{a}{d1}\frac{a}{d2}\cdots \frac{a}{d_k}\),当\(\frac{a^k}{D^k}==\frac{b}{D_k}\)时,有
\[\frac{a^k}{D_k}\cdot a^{x-k}\equiv \frac{b}{D_k}\pmod {\frac{p}{D_k}}\]即
\[a^{x-k}\equiv 1\pmod {\frac{p}{D_k}}\]于是\(x=k\)为解。其中\(k\)是正在进行的第\(k\)次约化。
代码实现
#include using namespace std;#define int long long#define reg registerinline int qpow(int a, int n, int p) { a%=p; int res=1; while (n) { if (n&1) res=res*a%p; a=a*a%p; n>>=1; } return res;}inline int bsgs(int a, int b, int k, int p) { int t=(int)(sqrt(p))+1; unordered_map h; h.clear(); int powa=1; for (reg int j=0; j=0 && i*t-j>=0) return i*t-j; powa=powa*a%p; } return -1;}inline int exbsgs(int a, int b, int p) { a%=p, b%=p; if (b==1 || p==1) return 0; int A=a, NA=1, B=b, P=p, k=0, D=1; while (__gcd(a,P)>1) { int d=__gcd(a,P); if (B%d) return -1; k++; A/=d, B/=d, P/=d, NA=NA*(a/d)%P, D=D*d%P; if (NA==B) return k; // NA就是上文提到的(a^k)/(D^k) } int res=bsgs(a,B,NA,P); if (res==-1) return res; if ((qpow(a,res+k,p)-b)%p) return -1; return res+k;}signed main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int a, b, p; while (cin>>a>>p>>b && a) { int res=exbsgs(a,b,p); if (res==-1) cout<<"No Solution\n"; else cout<
Record,\(2.46\rm{s}\),可以通过本题(包括Hack数据)。
后记
这道题算是比较毒瘤的,我是一共调了三天才过的(我太弱了)还有\(20\)天就要中考了,而我还在这摸鱼(悲)就谨此纪念一下我的初中OI生涯罢。
顺便在此祝福向宴酱中考顺利!
标签:
为您推荐
广告
- 当前快看:(ex)BSGS/(扩展)大步小步算法 学习笔记
- 美团众包需要买装备吗(美团众包不买装备能送多久)
- 小兔子图片画画_小兔子图片简笔画彩色
- 全球时讯:国防部长李尚福:各国管好自家的军舰飞机
- 风槿如画百度网盘_风槿如画
- 速递!金钱的魔力是几年级的课文_金钱的魔力主要内容
- 全球快资讯:盗窃罪构成的构成要件
- 每日速看!太平洋岛国不是大国博弈的竞技场
- 热门:房子漏水物业不处理怎么办
- 化工行业报价预警:安徽铠天化工产品有限责任公司四乙烯五胺价格4周暴涨871.43%(20230603)
- 5月环比增长的小鹏,仍需G6的“急救” 每日播报
- 英国铁路系统“罢工周”严重影响出行 谈判仍陷僵局
- 盼了十年的国产片,刚定档就被「禁」|环球热闻
- 【世界播资讯】烤羊肉酸菜腌制方法?
- 济南公务员平时考核管理信息系统入口_济南市公务员平时考核管理信息系统|全球视讯
- 护航“三夏”丨沁阳沁园覃怀街道:青春助力 三夏建功 环球要闻
- 京东白条逾期几天了会有什么后果(白条开了有什么后果)
- 每日速读!东百百货直营店_东百百货商场
- 全球头条:高质量发展调研行丨176比特“祖冲之号”量子计算云平台上线,面向全球开放
- 当前热文:重返20岁演员表图片_重返20岁演员表
广告
- 广州花都:“馆校合作”再添“文教”高质量发展新篇章 世界微资讯
- 世界头条:信用卡停息挂账怎么申请?分期算逾期吗?
- 厉飞雨是什么小说_历飞羽
- 深圳市坪山区事业单位招聘公告在哪里查(附入口)
- 影音爱好者首选笔记本神器|当前视点
- 临沂市沂河新区行政审批服务中心主任孙向堃同志一行莅临凯米特公司调研-天天热头条
- 2023铝塑膜行业市场运行现状及投资战略_环球百事通
- 环球今亮点!武南特高压交流工程跨鄱阳湖段开始放线
- 全球看热讯:邻苯二甲酸二丁酯商品报价动态(2023-06-02)
- 【通向玉山】“玉山”一词 因TA而来|微资讯
- 马自达cx5质量太他妈烂了(马自达cx5轮胎多久更换一次?)_今日快看
- 6月2日计算机设备行业十大熊股一览
- 保山“三化”建设打造强边固防升级版
- 第十一批国家节水型城市名单出炉|微头条
- 假面骑士时王:庄吾初变身像手办遭恶搞足够承包一天笑点|天天观热点
- 每日热讯!椰子角热量高嘛 椰子角
- 以标准化手段提升知识产权管理和创新能力 我国开展知识产权管理国际标准实施试点
- 天天热议:外媒:精神航空公司因技术问题导致逾三分之一航班延误
- 资讯推荐:语文中的论证思路怎么答_论证思路怎么答
- 当好孩子的“第一任老师” 环球动态