【学习笔记】原根 / BSGS / 扩展BSGS证明及模板

文章目录

  • 原根
  • BSGS大步小步算法
  • 扩展BSGS

原根

如果两个整数a,ba,ba,b互质,则有aϕ(b)%b=1a^{\phi(b)}\%b=1aϕ(b)%b=1

定义模bbb意义下的aaa的阶为使ad%b=1a^d\%b=1ad%b=1的最小正整数ddd

显然,模bbb的阶d∣ϕ(b)d|\phi(b)dϕ(b)

如果模bbb意义下aaa的阶为ϕ(b)\phi(b)ϕ(b),则称aaabbb原根

欧拉证明了(我证明不了)
在这里插入图片描述

bbb存在原根的充要条件为:b=2,4,pn,2pnb=2,4,p^n,2p^nb=2,4,pn,2pn,其中ppp为奇素数,n∈N∗n∈N^*nN

当模bbb有原根时,其原根个数为ϕ(ϕ(b))\phi(\phi(b))ϕ(ϕ(b))

那么如何求一个数的原根?

首先判断它是否有原根

如果有,一般最小原根都很小,可以选择美丽的暴力

预处理出ϕ(b)\phi(b)ϕ(b)的所有因子,存放在数组DDD

[2,ϕ(b))[2,\phi(b))[2,ϕ(b))区间中,从小到大米枚举变量iii

如果存在j∈Dj∈DjD,使得iϕ(b)j%b=1i^{\frac{\phi(b)}{j}}\%b=1ijϕ(b)%b=1,则iii不是原根,否则iii是原根

为什么这样是正确的呢?

因为如果存在一个数1≤x<ϕ(b)1\le x<\phi(b)1x<ϕ(b),使得ix%b=1i^x\%b=1ix%b=1

x∣ϕ(b)x|\phi(b)xϕ(b),并且一定存在一个ϕ(b)\phi(b)ϕ(b)的质因子jjj,使得x∣ϕ(b)jx|\frac{\phi(b)}{j}xjϕ(b)


BSGS大步小步算法

BSGS是用来解决离散对数问题

ax≡b(modp)a^x\equiv b\ (mod\ \ p)axb (mod  p),其中a,b,pa,b,pa,b,p已知,且(a,p)=1(a,p)=1(a,p)=1,求xxx

因为aϕ(p)≡1(modp),ϕ(p)<pa^{\phi(p)}\equiv 1\ (mod\ \ p),\phi(p)<paϕ(p)1 (mod  p),ϕ(p)<p

所以可以采取枚举法,在O(p)O(p)O(p)的时间复杂度求出xxx

BSGSBSGSBSGS可以在O(p)O(\sqrt{p})O(p)的时间复杂度内求出xxx

m=⌈p⌉,r=xmodmm=\lceil \sqrt{p} \rceil,r=x\mod mm=p,r=xmodm,则x=k∗m+rx=k*m+rx=km+r,其中0≤k<m,0≤r<k0\le k<m,0\le r<k0k<m,0r<k,有
ak∗m+r≡b(modp)a^{k*m+r}\equiv b\ \ (mod\ \ p)akm+rb  (mod  p)

因为(a,p)=1(a,p)=1(a,p)=1,方程两边同乘a−ra^{-r}ar

ak∗m≡b∗a−r(modp)a^{k*m}\equiv b*a^{-r}\ \ (mod\ \ p)akmbar  (mod  p)

对于0≤i<r0\le i<r0i<r,求出所有的b∗a−1modpb*a^{-1}\mod\ \ pba1mod  p,将其值以及iii存入mapmapmap

然后再求左边的aj∗mmodp,(0≤j<k)a^{j*m}\mod p,(0\le j<k)ajmmodp,(0j<k),并在mapmapmap里寻找是否出现过相同的值

如果有,代表着同余,已经找到了答案,如果没有则是无解

然而。。。

可以稍微转变一下算法过程,避免求逆元的操作
在这里插入图片描述

x=k∗m+r=(k+1)∗m−m+r=(k+1)∗m−(m−r)x=k*m+r=(k+1)*m-m+r=(k+1)*m-(m-r)x=km+r=(k+1)mm+r=(k+1)m(mr)
因为有 r<mr<mr<m 所以考虑换一种方式枚举 r←m−rr\leftarrow m-rrmr
⇒x=k∗m−r,(1≤k≤m,0≤r<m)\Rightarrow x=k*m-r,(1\le k\le m,0\le r<m)x=kmr(1km,0r<m)
ak∗m−r≡b(modp)a^{k*m-r}\equiv b\ \ (\mod p)akmrb  (modp)
两边同时乘以ara^rar
ak∗m≡b∗ar(modp)a^{k*m}\equiv b*a^r\ \ (\mod p)akmbar  (modp)
先求出右边所有的b∗ai(modp)(1≤i≤m)b*a^i(\mod p)(1\le i\le m)bai(modp)(1im)保存在mapmapmap

然后再求左边的aj∗mmodpa^{j*m}\mod\ pajmmod p,并在mapmapmap中查找是否出现过

如果出现过,左边枚举的是jjj,右边枚举的是iii,则答案为x=j∗m−ix=j*m-ix=jmi,这样就避免了求逆元的操作,却仍然用到了逆元

因为推导必须是等价推导,只有当(a,p)=1(a,p)=1(a,p)=1,即ara^rar逆元存在时,才可以大胆两边同乘ara^rar等价,因为如果(a,p)≠1(a,p)≠1(a,p)=1,式子倒推不回去

#include <map>
#include <cmath>
#include <cstdio>
using namespace std;
#define int long long
map < int, int > mp;
int a, mod, r;int bsgs() {mp.clear();int m = ceil( sqrt( mod ) );int tmp = 1;for( int i = 1;i <= m;i ++ ) {tmp = tmp * a % mod;mp[tmp * r % mod] = i;}int res = 1;for( int i = 1;i <= m;i ++ ) {res = res * tmp % mod;if( mp[res] ) return m * i - mp[res];}return -1;
}signed main() {int ans;while( ~ scanf( "%lld %lld %lld", &mod, &a, &r ) ) {r %= mod, a %= mod;if( r == 1 ) ans = 0;else if( ! a ) {if( r ) ans = -1;else ans = 1;}else ans = bsgs();if( ans == -1 ) printf( "no solution\n" );else printf( "%lld\n", ans );}return 0;
}

扩展BSGS

对于ax≡b(modp)a^x\equiv b(\mod p)axb(modp)

如果(a,p)>1(a,p)>1(a,p)>1,则无法直接套用BSGS,此时就要用到扩展BSGS

将要求解的式子变形
ax+k∗p=ba^x+k*p=bax+kp=b
(a,p)=g(a,p)=g(a,p)=g,若bbb不是ggg的倍数,则方程无解

不过有一个例外b=1,x=0b=1,x=0b=1,x=0,这个情况特判即可

式子左右两边除以ggg
ax−1ag+kpg=bga^{x-1}\frac{a}{g}+k\frac{p}{g}=\frac{b}{g}ax1ga+kgp=gb
a′=ag,p′=pg,b′=bga'=\frac{a}{g},p'=\frac{p}{g},b'=\frac{b}{g}a=ga,p=gp,b=gb
ax−1a′+kp′=b′a^{x-1}a'+kp'=b'ax1a+kp=b
a,p′a,p'a,p仍然不互质,则继续以上操作找出a,p′a,p'a,p的最大公约数g′g'g

最新式子两边继续除以g′g'g,直到(a,p′)=1(a,p')=1(a,p)=1为止

在此过程中,假设取出来了cntcntcntaaa,出去公约数后剩下的乘积为a′a'a

此时(a′,p′)=1(a',p')=1(a,p)=1,于是可以转化为ax−cnta′≡b(modp)⇔ax−cnt≡b′(a′)−1(modp)a^{x-cnt}a'\equiv b\pmod p \Leftrightarrow a^{x-cnt}\equiv b'(a')^{-1}\pmod paxcntab(modp)axcntb(a)1(modp)
其中cntcntcnt表示两边除以最大公约数ggg的次数

此处右边有逆元,为了避免求逆元,将a′a'a保留在左边

在BSGS枚举左边时,初始值设为a′a'a即可

如果在除以ggg的过程中,发现b′(a′)−1=1⇔b′≡a′⇒x−cnt=0⇒x=cntb'(a')^{-1}=1\Leftrightarrow b'\equiv a'\Rightarrow x-cnt=0\Rightarrow x=cntb(a)1=1baxcnt=0x=cnt

接下来,直接套用基础BSGS即可,记得最后的答案不要忘记加上cntcntcnt哟(^U^)ノ~YO
在这里插入图片描述

#include <map>
#include <cmath>
#include <cstdio>
using namespace std;
#define int long long
map < int, int > mp;
int a, mod, r;int gcd( int x, int y ) {if( ! y ) return x;else return gcd( y, x % y );
}int qkpow( int x, int y, int mod ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}int exbsgs() {if( r == 1 ) return 0;int cnt = 0, tmp = 1, d;while( 1 ) {d = gcd( a, mod );if( d == 1 ) break;if( r % d ) return -1;r /= d, mod /= d;tmp = tmp * ( a / d ) % mod;++ cnt;if( tmp == r ) return cnt;}mp.clear();int res = r;mp[r] = 0;int m = ceil( sqrt( 1.0 * mod ) );for( int i = 1;i <= m;i ++ ) {res = res * a % mod;mp[res] = i;}int temp = qkpow( a, m, mod );res = tmp;for( int i = 1;i <= m;i ++ ) {res = res * temp % mod;if( mp.count( res ) )return i * m - mp[res] + cnt;}return -1;
}signed main() {while( ~ scanf( "%lld %lld %lld", &a, &mod, &r ) ) {if( ! a && ! mod && ! r ) return 0;int ans = exbsgs();if( ans == -1 ) printf( "No Solution\n" );else printf( "%lld\n", ans );}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317849.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.Net Core分布式部署中的DataProtection密钥安全性

在.NetCore中默认使用DataProtection来保护数据&#xff0c;例如Cooike等。一般情况下DataProtection生成的密钥会被加密后存储&#xff0c;例如默认的文件存储可以看到使用了Windows DPAPI加密。但是如果更改默认设置例如使用的外部存储如redis则此时密钥默认是不加密的微软说…

scanf(“%s“)真的只开读入字符串大小就可以了吗??

文章目录前言还原过程计算机程序背后的故事总结瞎逼逼前言 艹艹艹艹艹艹&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;老子没想到没想到&#xff0c;靠&#xff01; 本人刚刚在做树链剖分“染色”一题的代码重构&#xff0c;上午打…

P5299-[PKUWC2018]Slay the Spire【dp】

前言 正题 题目链接:https://www.luogu.com.cn/problem/P5299 题目大意 有2n2n2n张牌&#xff0c; nnn张强化牌&#xff0c;每张上有一个正整数x(x>1)x(x>1)x(x>1)&#xff0c;如果使用后之后的每一张攻击牌伤害都会乘上xxx。nnn张攻击牌&#xff0c;每张上有一个正…

asp.net core2.2 多用户验证和授权

asp.net core2.2 用户验证 和授权有很详细和特贴心的介绍&#xff0c;我感兴趣的主要是这两篇&#xff1a;cookie身份验证基于角色的授权我的项目有两类用户&#xff1a;微信公众号用户&#xff0c;用户名为公众号的openid企业微信的用户&#xff0c;用户名为企业微信的userid每…

P1494 [国家集训队]小Z的袜子

P1494 [国家集训队]小Z的袜子 题意&#xff1a; 有一个长度为 n 的序列c[i] 。现在给出 m个询问&#xff0c;每次给出两个数l,r &#xff0c;从编号在 l 到 r 之间的数中随机选出两个不同的数&#xff0c;求两个数相等的概率。 题解&#xff1a; 很明显&#xff0c;莫队算法…

一文带你快速读懂.NET CLI

dotnet cli 是 .Net Core 功能中最有用的特性之一。在这篇文章里&#xff0c;我们将介绍几个.Net OSS 工具是如何使用 dotnet cli&#xff0c;并介绍如何在日常开发中使用新的 cli 工具。正文关键要点dotnet cli 使得基于. Net 项目的自动化和脚本编写变得非常简单&#xff0c;…

[POJ 3164]Command Network(最小树形图,朱刘算法)

文章目录titlesolutioncodetitle solution 读完翻译后&#xff0c;很明显就是个朱刘算法的板子题 最小树形图&#xff0c;就是给出一个带权有向图 从中指定一个特殊的结点 root 求一棵以 root 为根的有向生成树 T&#xff0c;且使得 T 中所有边权值最小 简单来说&#xff0c…

ASP.NET Core 3.0:将会拥有更少的依赖

在ASP.NET Core项目中&#xff0c;我们使用一个叫做Microsoft.AspNetCore.App的综合包。它也被称为ASP.NET Core Shared Framework&#xff0c;在ASP.NET Core Shared Framework之中包含了很多依赖项&#xff0c;它能满足一般应用的需求。但是如果你查看它的依赖项&#xff0c;…

CSP2021NOIP2021游记

CSP Day -? 初赛 初赛考前没怎么复习&#xff0c;反倒是理直气壮的翘了一周晚修&#xff08;虽然后面就一直翘了&#xff09;。 开考之后才发现要拿那几张纸&#xff0c;监考让我考完再出去拿。 选择题很简单&#xff0c;没有啥犹豫的写完了&#xff0c;第一道读程序写结果好…

微软上线Try .NET,支持在浏览器运行C#代码

微软Try .NET项目近期上线&#xff0c;这一项目允许用户通过浏览器运行和编写C#代码&#xff0c;同时还支持完整的代码提示。用户可以通过访问这一项目官网&#xff08;点此进入&#xff09;对Try .NET这一项目进行简单了解。该项目允许开发人员在浏览器中运行和编辑C#代码片段…

[LOJ]体育成绩统计 / Score (无脑模拟,没有脑子,就是上!)

题目 好久没敲过恶心的模拟题了&#xff0c;莫名有点怀念是什么鬼&#xff0c;我还记得我的zamjena 没啥想说的&#xff0c;这道题就是没智商有码力的 纯粹是纪念一下今天上午直接肝了的两个半小时&#xff0c;真的一点思维都不需要有&#xff0c;直接上&#xff01;&#xff0…

程序员修仙之路--设计一个实用的线程池

菜菜呀&#xff0c;我最近研究技术呢&#xff0c;发现线上一个任务程序线程数有点多呀CEO,CTO,CFO于一身的CXOx总&#xff0c;你学编程呢&#xff1f;菜菜作为公司总负责人&#xff0c;我以后还要管理技术部门呢&#xff0c;怎么能不会技术呢CEO,CTO,CFO于一身的CXO&#xff08…

Code Names

Code Names 题意&#xff1a; 如果一个字符串通过交换两个位置可以得到另一个字符串&#xff08;也就是两个字符串只有两个位置不一样且为交换关系&#xff09;&#xff0c;我们称这两个字符串为替代关系。 现在给出n个字符串&#xff0c;求一个集合&#xff0c;使得集合内的…

【2020牛客NOIP赛前集训营-提高组(第一场)题解】( 牛牛的方程式,牛牛的猜球游戏,牛牛的凑数游戏,牛牛的RPG游戏)

未完待续...T1&#xff1a;牛牛的方程式titlesolutioncodeT2&#xff1a;牛牛的猜数游戏titlesolutioncodeT3&#xff1a;牛牛的凑数游戏titlesolutioncodeT1&#xff1a;牛牛的方程式 title solution 因为浮点错误炸了70pts 这个三元一次不定方程呢&#xff0c;其实也没有…

程序员修仙之路-数据结构之 CXO让我做一个计算器

菜菜呀&#xff0c;个税最近改革了&#xff0c;我得重新计算你的工资呀&#xff0c;我需要个计算器&#xff0c;你开发一个吧CEO,CTO,CFO于一身的CXOX总&#xff0c;咱不会买一个吗&#xff1f;菜菜那不得花钱吗&#xff0c;一块钱也是钱呀这个计算器支持加减乘除运算就行&…

P5518-[MtOI2019]幽灵乐团【莫比乌斯反演,欧拉反演】

正题 题目链接:https://www.luogu.com.cn/problem/P5518 题目大意 TTT次给出A,B,CA,B,CA,B,C求以下三个式子 ∏i1A∏j1B∏k1Clcm(i,j)gcd(i,k)\prod_{i1}^A\prod_{j1}^B\prod_{k1}^{C}\frac{lcm(i,j)}{gcd(i,k)}i1∏A​j1∏B​k1∏C​gcd(i,k)lcm(i,j)​ ∏i1A∏j1B∏k1C(lcm(…

【2020牛客NOIP赛前集训营-提高组(第二场)】题解(GCD,包含,前缀,移动)

文章目录T1&#xff1a;GCDtitlesolutioncodeT2&#xff1a;包含titlesolutioncode(正解code补充在上面了)T3&#xff1a;前缀titlesolutioncodeT4&#xff1a;移动titlesolutioncodeT1&#xff1a;GCD title solution 非常水&#xff0c;看一眼就知道了 首先我们知道每一个…

.NET Core实战项目之CMS 第十五章 各层联动工作实现增删改查业务

连着两天更新叙述性的文章大家可别以为我转行了&#xff01;哈哈&#xff01;今天就继续讲讲我们的.NET Core实战项目之CMS系统的教程吧&#xff01;这个系列教程拖得太久了&#xff0c;所以今天我就以菜单部分的增删改查为例来讲述下我的项目分层之间的协同工作吧&#xff01;…

[2020-11-23 contest]图(dfs剪枝),劫富济贫(字典树),小A的树(树形DP),游戏(贪心/斜率优化)

文章目录T1&#xff1a;图solutioncodeT2&#xff1a;劫富济贫solutioncodeT3&#xff1a;小A的树solutioncodeT4&#xff1a;游戏solutioncodeT1&#xff1a;图 【问题描述】 给你一个n个点&#xff0c;m条边的无向图&#xff0c;每个点有一个非负的权值ci&#xff0c;现在你…

P1742 最小圆覆盖

P1742 最小圆覆盖 题意&#xff1a; 给出N个点&#xff0c;让你画一个最小的包含所有点的圆。 题解&#xff1a; 先说结论&#xff1a; 最优解的圆一定是在以某两个点连线为直径的圆 或者 某三个点组成的三角形的外接圆 初始化将某个圆心定为第一个点&#xff0c;R0 枚举第…