首页 > 其他分享 >原根 学习笔记

原根 学习笔记

时间:2024-07-04 13:09:59浏览次数:14  
标签:ab 原根 pmod varphi 学习 笔记 delta equiv

先看看啥是.

由欧拉定理可知,对于 \(a\in\mathbf{Z},m\in\mathbf{N}^*\) ,若 \((a,m)=1\) ,则 \(a^{\varphi(m)}\equiv1\pmod m\) .
因此满足同余式 \(a^n\equiv1\pmod m\) 的最小正整数 \(n\) 存在,这个 \(n\) 称作 \(a\) 模 \(m\) 的阶,记作 \(\delta_m(a)\) 或 \(\operatorname{ord}_m(a)\) .

再看看有啥性质.

  1. \(a,a^2,\dots,a^{\delta_m(a)}\) 模 \(m\) 两两不同余.
  2. 若 \(a^n\equiv1\pmod m\) ,则 \(\delta_m(a)|n\) .
  3. 设 \(m\in\mathbf{N}^*,a\in\mathbf{Z},b\in\mathbf{Z},(a,m)=(b,m)=1\) ,
    则 \(\delta_m(ab)=\delta_m(a)\delta_m(b)\) 的充要条件为 \((\delta_m(a),\delta_m(b))=1\) .
  • 证明必要性:
点击查看证明 易知 $a^{\delta_m(a)}\equiv1\pmod m,b^{\delta_m(b)}\equiv1\pmod m$ ,

则 \((ab)^{[\delta_m(a),\delta_m(b)]}\equiv1\pmod m\) ,

可知 \(\delta_m(ab)|[\delta_m(a),\delta_m(b)]\) ,

又因为 \(\delta_m(ab)=\delta_m(a)\delta_m(b)\) ,

所以 \(\delta_m(a)\delta_m(b)|[\delta_m(a),\delta_m(b)]\) ,

所以 \((\delta_m(a),\delta_m(b))=1\) .

  • 证明充分性:
点击查看证明 易知 $(ab)^{\delta_m(ab)}\equiv1\pmod m$ ,

则 \((ab)^{\delta_m(ab)}\equiv(ab)^{\delta_m(ab)\delta_m(b)}\equiv a^{\delta_m(ab)\delta_m(b)}\equiv1\pmod m\) ,

所以 \(\delta_m(a)|\delta_m(ab)\delta_m(b)\) ,

又因为 \((\delta_m(a),\delta_m(b))=1\) ,

所以 \(\delta_m(a)|\delta_m(ab)\) ,

同理 \(\delta_m(b)|\delta_m(ab)\) ,

所以 \(\delta_m(a)\delta_m(b)|\delta_m(ab)\) ,

又因为 \((ab)^{\delta_m(a)\delta_m(b)}\equiv(a^{\delta_m(a)})^{\delta_m(b)}(b^{\delta_m(b)})^{\delta_m(a)}\equiv1\pmod m\) ,

所以 \(\delta_m(ab)|\delta_m(a)\delta_m(b)\) ,

综上 \(\delta_m(ab)=\delta_m(a)\delta_m(b)\) .

  1. 设 \(k\in\mathbf{N},m\in\mathbf{N}^*,a\in\mathbf{Z},(a,m)=1\) ,则 \(\delta_m(a^k)=\dfrac{\delta_m(a)}{(\delta_m(a),k)}\) .
  • 证明:
点击查看证明 注意到 $a^{k\delta_m(a^k)}\equiv (a^k)^{\delta_m(a^k)}\equiv1\pmod m$ ,

则 \(\delta_m(a)|k\delta_m(a^k)\) ,即 \(\dfrac{\delta_m(a)}{(\delta_m(a),k)}|\delta_m(a^k)\) ,

又注意到 \((a^k)^{\frac{\delta_m(a)}{(\delta_m(a),k)}}\equiv(a^{\delta_m(a)})^{\frac{k}{(\delta_m(a),k)}}\equiv1\pmod m\) ,

则 \(\delta_m(a^k)|\dfrac{\delta_m(a)}{(\delta_m(a),k)}\) ,

综上 \(\delta_m(a^k)=\dfrac{\delta_m(a)}{(\delta_m(a),k)}\) .


原根

说完,再看看啥是原根.

设\(m\in\mathbf{N}^*,g\in\mathbf{Z}\) .若 \((g,m)=1\) ,且 \(\delta_m(g)=\varphi(m)\),则称 \(g\) 为模 \(m\) 的原根.

原根有什么性质呢?

  1. (原根判定定理)设 \(m\geqslant3,(g,m)=1\) ,则 \(g\) 是模 \(m\) 的原根的充要条件为,对于 \(\varphi(m)\) 的每个素因数 \(p\) ,都有 \(g^{\frac{\varphi(m)}{p}}\not\equiv1\pmod m\)
  • 证明充分性:
点击查看证明 使用反证法.

当对于 \(\varphi(m)\) 的每个素因数 \(p\) ,都有 \(g^{\frac{\varphi(m)}{p}}\not\equiv 1\pmod m\) 成立时,我们假设存在一个 \(g\),其不是模 \(m\) 的原根.

因为 \(g\) 不是 \(m\) 的原根,则存在一个 \(t<\varphi(m)\) 使得 \(g^t\equiv 1\pmod{m}\) .

由裴蜀定理得,一定存在一组 \(k,x\) 满足 \(kt=x\varphi(m)+(t,\varphi(m))\) .

又由欧拉定理得 \(g^{\varphi(m)}\equiv 1\pmod{m}\) ,故有:

\[1\equiv g^{kt}\equiv g^{x\varphi(m)+(t,\varphi(m))}\equiv g^{(t,\varphi(m))}\pmod{m} \]

由于 \((t, \varphi(m)) \mid \varphi(m)\) 且 \((t, \varphi(m))\leqslant t < \varphi(m)\) .

故存在 \(\varphi(m)\) 的素因数 \(p\) 使得 \((t, \varphi(m)) \mid \frac{\varphi(m)}{p}\) .

则 \(g^{\frac{\varphi(m)}{p}}\equiv g^{(t, \varphi(m))}\equiv 1\pmod{m}\) ,与条件矛盾.

故假设不成立,原命题成立.

  1. (原根个数)若一个数 \(m\) 有原根,则它原根的个数为 \(\varphi(\varphi(m))\) .
  • 证明:
点击查看证明 若 $m$ 有原根 $g$ ,则:

\[\delta_m(g^k)=\dfrac{\delta_m(g)}{\left(\delta_m(g),k\right)}=\dfrac{\varphi(m)}{\left(\varphi(m),k\right)} \]

所以若 \(\left(k,\varphi(m)\right)=1\) ,则有: \(\delta_m(g^k)=\varphi(m)\) ,即 \(g^k\) 也是模 \(m\) 的原根.

而满足 \(\left(\varphi(m),k\right)=1\) 且 \(1\leq k \leq \varphi(m)\) 的 \(k\) 有 \(\varphi(\varphi(m))\) 个.所以原根就有 \(\varphi(\varphi(m))\) 个.

  1. (原根存在定理)一个数 \(m\) 存在原根当且仅当 \(m=2,4,p^{\alpha},2p^{\alpha}\) ,其中 \(p\) 为奇素数, \(\alpha\in \mathbf{N}^{*}\) .
  1. (最小原根的范围估计) 见 OI-Wiki .

题目

题单: https://vjudge.net/contest/638199 .

洛谷 P6081 【模板】原根

https://www.luogu.com.cn/article/d1yftjt7 .

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1000010;
int t,p,cnt,tot,ctans,fc[MAXN],ans[MAXN],pri[MAXN],rt[MAXN],q[MAXN],phi[MAXN];
void init () {
	phi[1]=1;
	for (int i=2;i<=MAXN-10;i++) {
		if (!q[i]) {pri[++tot]=i,phi[i]=i-1;}
		for (int j=1;j<=tot&&pri[j]*i<=MAXN-10;j++) {
			q[i*pri[j]]=1;
			if (i%pri[j]==0) {
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
	rt[2]=rt[4]=1;
	for (int i=2;i<=tot;i++) {
		for (int j=1;(1ll*j*pri[i])<=MAXN-10;j*=pri[i]) {rt[j*pri[i]]=1;}
		for (int j=2;(1ll*j*pri[i])<=MAXN-10;j*=pri[i]) {rt[j*pri[i]]=1;}
	}
	return;
}
int gcd (int a,int b) {return (b==0?a:gcd(b,a%b));}
int qpow (int a,int b,int p) {
	int res=1;
	while (b) {
		if (b&1) {res=(1ll*res*a)%p;}
		a=(1ll*a*a)%p;
		b>>=1;
	}
	return res;
}
void proc (int p) {
	for (int i=2;i*i<=p;i++) {
		if (p%i==0) {
			fc[++cnt]=i;
			while (p%i==0) {p/=i;}
		}
	}
	if (p>1) {fc[++cnt]=p;}
	return;
}
bool chk (int x,int p) {
	if (qpow(x,phi[p],p)!=1) {return 0;}
	for (int i=1;i<=cnt;i++) {
		if (qpow(x,phi[p]/fc[i],p)==1) {return 0;}
	}
	return 1;
}
int findrt (int p) {
	for (int i=1;i<p;i++) {
		if (chk(i,p)) {return i;}
	}
	return 0;
}
void getrt (int p,int x) {
	int prod=1;
	for (int i=1;i<=phi[p];i++) {
		prod=(1ll*prod*x)%p;
		if (gcd(i,phi[p])==1) {
			ans[++ctans]=prod;
		}
	}
	return;
}
int main () {
	init();
	scanf("%d",&t);
	for (int ii=1;ii<=t;ii++) {
		int wtf;
		scanf("%d%d",&p,&wtf);
		if (rt[p]) {
			ctans=cnt=0;
			proc(phi[p]);
			int mn=findrt(p);
			getrt(p,mn);
			sort(ans+1,ans+ctans+1);
			printf("%d\n",ctans); 
			for (int i=1;i<=ctans/wtf;i++) {printf("%d ",ans[i*wtf]);}
			printf("\n");
		} else {
			printf("0\n\n");
		}
	}
	return 0;
}

POJ 1284 Primitive Roots

直接求 \(\varphi(\varphi(p))\) 即可.

点击查看代码
#include <iostream>
using namespace std;
const int N = 65536;
bool ok[N + 5];
int phi[N + 5], pri[N + 5], tot = 0;
void init() {
    phi[1] = 1;
    for (int i = 2; i <= N; i++) {
        if (!ok[i]) {
            pri[++tot] = i;
            phi[i] = i - 1;
        }
        for (int j = 1; i * pri[j] <= N && j <= tot; j++) {
            if (i % pri[j] == 0) {
                phi[i * pri[j]] = phi[i] * pri[j];
                break;
            }
            ok[i * pri[j]] = true;
            phi[i * pri[j]] = phi[i] * (pri[j] - 1);
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    init();
    int p;
    while (cin >> p)
        cout << phi[phi[p]] << endl;
    return 0;
}

CodeForces 615D Multipliers

CodeForces 360D Levko and Sets

CodeForces 284A Cows and Primitive Roots

AtCoder abc335_g Discrete Logarithm Problems

AtCoder abc212_h Nim Counting

标签:ab,原根,pmod,varphi,学习,笔记,delta,equiv
From: https://www.cnblogs.com/01bit/p/18282900

相关文章

  • 从零开始学习数据结构--2.1线性表之顺序表
    到这一章线性表,我们要掌握的就多了。1.线性表的定义线性表是n个具有相同特性的数据元素的有限序列。我们可以理解为幼儿园排队,在幼儿园里面,每个小朋友都是有一定的序号的,小朋友可以领到他们的专属号码,比如说小明是一号,小花是二号......那么,我们就可以说幼儿园小朋友排队属于......
  • 一文读懂HW护网行动(附零基础学习教程)
    前言随着《网络安全法》和《等级保护制度条例2.0》的颁布,国内企业的网络安全建设需与时俱进,要更加注重业务场景的安全性并合理部署网络安全硬件产品,严防死守“网络安全”底线。“HW行动”大幕开启,国联易安誓为政府、企事业单位网络安全护航!网络安全形势变得尤为复杂严峻。......
  • 大一新手小白如何学习编程
    学习编程对于大一新手来说,可能会显得有些困难和复杂,但只要找到正确的方法和策略,就能事半功倍。1.选择适合的编程语言首先,你需要选择一门适合初学者的编程语言。Python是一个非常好的选择,因为它的语法简单易懂,广泛应用于数据分析、人工智能、Web开发等多个领域。除此之外,Jav......
  • 暑假集训学习笔记(3):lxl DS Day 3
    区间最值操作CF1572F首先广播站\(i\),能覆盖到的肯定是相对于\(i\)的前缀,我们可以维护一个\(r_i\),表示每个\(i\)可以覆盖到的右端点,然后我们考虑segmentbeats,考虑\(max\)变为\(v\)时,我们维护最大值有多少个,然后对应的\(b\)数组的\([v+1,max]\)位置就区......
  • 作为程序员的他,大学四年一直自学,全靠这些实用工具和学习网站!
    鸡腿哥,你好,马上6月份就要毕业了。非常感谢这些年来鸡腿哥的鼓励,你的那些文章我基本上都看了,尤其是程序人生方面的文章给我启迪很大。大学四年,我没有白过,虽然专业不是程序员,但我喜欢这个行业,一直在自学,并且收集了不少实用工具和学习网站,希望借助二哥的影响力传播给更多新......
  • java笔记分享(6)
    RandomRandom类        Random类位于java.util包下,Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。        相同种子数的Random对象,相同次数......
  • 机器学习原理之 -- 最近邻算法分类:由来及原理详解
            最近邻算法(k-NearestNeighbors,k-NN)是一种简单且直观的分类算法,广泛应用于分类和回归问题。由于其易于理解和实现,k-NN在数据挖掘、模式识别和机器学习领域中占据重要地位。本文将详细介绍最近邻算法的由来、基本原理、构建过程及其优缺点。二、最近邻算法的由......
  • IJCV 2024 | CoCoNet:用于多模态图像融合的耦合对比学习网络与多级特征集成
    CoCoNet:CoupledContrastiveLearningNetworkwithMulti-levelFeatureEnsembleforMulti-modalityImageFusionCoCoNet:用于多模态图像融合的耦合对比学习网络与多级特征集成JinyuanLiu;RunjiaLin;GuanyaoWu;RishengLiu;Zhongxuan;LuoXinFan更多TPAMI,IJCV......
  • OpenStack Yoga版安装笔记(四)keystone练习
    1、keyston安装过程在安装过程中,首先需要在controllernode上的MariaDB中创建一个名为keystone的数据库。接着,在controllernode上安装Keystone软件包,并配置数据库连接。Keystone和数据库可以部署在不同的服务器上,Keystone通过解析主机名“controller”来访问数据库。2、......
  • 算法金 | 致敬深度学习三巨头:不愧是腾讯,LeNet问的巨细。。。
    ​大侠幸会,在下全网同名「算法金」0基础转AI上岸,多个算法赛Top「日更万日,让更多人享受智能乐趣」抱个拳,送个礼读者参加面试,竟然在LeNet这个基础算法上被吊打~LeNet确实经典,值得好好说道说道更多内容,见微*公号往期文章:有史以来最详细的卷积神经网络(CNN)及其变体......