原根(详解+代码实现+例题+快速求解一个数的原根)
1.原根定义
欧拉定理(也称费马-欧拉定理或欧拉函数定理)是一个关于同余的性质。欧拉定理表明,若为正整数,且互素(即),则
2.如何求解:
一、枚举
从2开始枚举,然后暴力判断g^(P-1) = 1 (mod P)是否当且当指数为P-1的时候成立
二、讲究方法
例如求任何一个质数x的任何一个原根,一般就是枚举2到x-1,并检验。有一个方便的方法就是,求出x-1所有不同的质因子p1,p2...pm,对于任何2<=a<=x-1,判定a是否为x的原根,只需要检验a^((x-1)/p1),a^((x-1)/p2),...a^((x-1)/pm)这m个数中,是否存在一个数mod x为1,若存在,a不是x的原根,否则就是x的原根。
原来的复杂度是O(P-1),现在变成O(m)*log(P-1)m为x-1质因子的个数。很明显质因子的个数远远小于x-1。
证明可用欧拉定理和裴蜀定理:
裴蜀定理
说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式):
ax + by = m
有解当且仅当m是d的倍数。裴蜀等式有解时必然有无穷多个整数解,每组解x、y都称为裴蜀数,可用辗转相除法求得。
例如,12和42的最大公因子是6,则方程12x + 42y = 6有解。事实上有(-3)×12 + 1×42 = 6及4×12 + (-1)×42 = 6。
特别来说,方程 ax + by = 1 有解当且仅当整数a和b互素。
裴蜀等式也可以用来给最大公约数定义:d其实就是最小的可以写成ax + by形式的正整数。这个定义的本质是整环中“理想”的概念。因此对于多项式整环也有相应的裴蜀定理。
证明
- 若存在,那么显然的事情
- 否则,假设存在一个t<phi(x)=x-1使得a^t = 1 (mod x)
- 那么由裴蜀定理,一定存在一组k,r使得kt=(x-1)r+gcd(t,x-1)
- 而由欧拉定理有,a^(x-1) = 1 (mod x)
- 于是1 = a^(kt) = a^(xr-r+gcd(t,x-1)) = a^gcd(t,x-1) (mod x)
- 而t<x-1故gcd(t,x-1)<x-1
- 又gcd(t,x-1)|x-1 于是gcd(t,x-1)必整除(x-1)/p1,(x-1)/p2...(x-1)/pm其中至少一个,设其一为(x-1)/pi
- 那么a^((x-1)/pi) = (a^gcd(t,x-1))^s = 1^s = 1 (mod x)
- 这与假设矛盾
代码:
来至http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135的一道题目:
题目
<span id="Showjim86_bnbbbsbl_s39"></span>输入1个质数P(3 <= P <= 10^9)<span id="Showjim86_bnbbbsbl_e39"></span>
<span id="Showjim86_bnbbbsbl_s40"></span>输出P最小的原根。
解答
- #include <iostream>
- #include <cstdlib>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- int P;
- const int NUM = 32170;
- int prime[NUM/4];
- bool f[NUM];
- int pNum = 0;
- void getPrime()//线性筛选素数
- {
- for (int i = 2; i < NUM; ++ i)
- {
- if (!f[i])
- {
- f[i] = 1;
- prime[pNum++] = i;
- }
- for (int j = 0; j < pNum && i*prime[j] < NUM; ++ j)
- {
- f[i*prime[j]] = 1;
- if (i%prime[j] == 0)
- {
- break;
- }
- }
- }
- }
- __int64 getProduct(int a,int b,int P)//快速求次幂mod
- {
- __int64 ans = 1;
- __int64 tmp = a;
- while (b)
- {
- if (b&1)
- {
- ans = ans*tmp%P;
- }
- tmp = tmp*tmp%P;
- b>>=1;
- }
- return ans;
- }
- bool judge(int num)//求num的所有的质因子
- {
- int elem[1000];
- int elemNum = 0;
- int k = P - 1;
- for (int i = 0; i < pNum; ++ i)
- {
- bool flag = false;
- while (!(k%prime[i]))
- {
- flag = true;
- k /= prime[i];
- }
- if (flag)
- {
- elem[elemNum ++] = prime[i];
- }
- if (k==1)
- {
- break;
- }
- if (k/prime[i]<prime[i])
- {
- elem[elemNum ++] = prime[i];
- break;
- }
- }
- bool flag = true;
- for (int i = 0; i < elemNum; ++ i)
- {
- if (getProduct(num,(P-1)/elem[i],P) == 1)
- {
- flag = false;
- break;
- }
- }
- return flag;
- }
- int main()
- {
- getPrime();
- while (cin >> P)
- {
- for (int i = 2;;++i)
- {
- if (judge(i))
- {
- cout << i<< endl;
- break;
- }
- }
- }
- return 0;
- }
原根(详解+代码实现+例题+快速求解一个数的原根)相关推荐
- 原根-快速求解一个数的原根
1.原根定义 假设一个数g对于P来说是原根,那么g^i mod P的结果两两不同,且有 1<g<P, 1<i<P,那么g可以称为是P的一个原根 简单来说,g^i mod p ≠ ...
- SpringBoot详解(一)-快速入门
SpringBoot详解系列文章: SpringBoot详解(一)-快速入门 SpringBoot详解(二)-Spring Boot的核心 SpringBoot详解(三)-Spring Boot的we ...
- .user.ini上传详解附CTF例题
.user.ini上传详解附CTF例题 题目 解法 https://buuoj.cn/challenges#[SUCTF%202019]CheckIn [SUCTF 2019]CheckIn 题目 解 ...
- 五分钟搞懂后缀数组!后缀数组解析以及应用(附详解代码)
为什么学后缀数组 后缀数组是一个比较强大的处理字符串的算法,是有关字符串的基础算法,所以必须掌握. 学会后缀自动机(SAM)就不用学后缀数组(SA)了?不,虽然SAM看起来更为强大和全面,但是有些SA ...
- 腐烂国度2怎么学计算机知识,腐烂国度2操作方法详解 教你如何快速掌握操作方法...
腐烂国度2操作方法详解 教你如何快速掌握操作方法 很多小伙伴买了腐烂国度2不知道怎么玩,刚上手连操作按键在哪都不知道.下面小编就为大家带来了腐烂国度2操作方法详解 教你如何快速掌握操作方法. 基本操作 ...
- 『ML笔记』HOG特征提取原理详解+代码
HOG特征提取原理详解+代码! 文章目录 一. HOG特征介绍 二. HOG算法具体流程+代码 2.1. 图像灰度化和gamma矫正 2.2. 计算图像像素梯度图 2.3. 在8×8的网格中计算梯度直 ...
- 24.shell中list详解,定义list,获取List的总个数,获取list的某个元素值,将list的每个元素转换成以空格分隔的字符串,空格分隔的字符串转换成list,for循环list
文章目录 前言 定义list 获取List的总个数 获取list的某个元素值 将list的每个元素转换成以空格分隔的字符串 空格分隔的字符串转换成list for循环list 总结 友情链接 前言 s ...
- [学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]
文章目录 引入概念 全套模板 变量声明 update ==rotate旋转== splay操作 insert插入 delete删除 查找x的位置 查找第k大 前驱/后继 极小值-inf和极大值inf的 ...
- xvid 详解 代码分析 编译等
1. Xvid参数详解 众所周知,Mencoder以其极高的压缩速率和不错的画质赢得了很多朋友的认同! 原来用Mencoder压缩Xvid的AVI都是使用Xvid编码器的默认设置,现在我来给大家冲 ...
最新文章
- 【数据平台】Eclipse+MapReduce开发环境(集群运行模式)
- [Elasticsearch] 邻近匹配 (二) - 多值字段,邻近程度与相关度
- 数据结构-栈之二进制转十进制和八进制
- java制作五子棋的论文,基于java的五子棋的设计与实现.docx
- java 获取发布后的路径问题_Java中的路径问题实例分析
- Two-Stream RNN/CNN for Action Recognition in 3D Videos-阅读笔记
- 定个小目标,炒股咯....
- excel两个表格数据对比_Excel表格技巧—如何统计数据个数
- Robocopy命令实现文件服务器每日镜像备份/增量备份操作
- 【杂谈】Windows安装Fluent Terminal
- 抖音旋转很炫的html,火爆抖音的旋转时钟屏保,超酷超炫的
- 《计算机网络》在物理层和数据链路层扩展以太网
- 如何快速合并PDF文件?几个方法教你合并PDF
- 考试试卷用什么纸打印,哪里打印试卷便宜
- 解决无法设置默认打开方式
- ROS到ROS2的多节点组合运行
- 编译工具 Ninja 介绍
- 软件开发,如何快速有效缩短项目周期
- 【人工智能】3.谓词与机器推理
- win10系统,点击连接校园网WLAN后,弹不出登录网页
热门文章
- 现代软件工程 第八章 【需求分析】练习与讨论
- java数组有跨类建立对象_必会的 55 个 Java 性能优化细节!一网打尽!
- Linux基本目录结构
- JAVA入门级教学之(参数传递)
- JAVA入门级教学之(if语句)
- python指定条件分类输出_python基础(二)条件判断、循环、格式化输出
- 程序员的数学 pdf_作为一个程序员,分享我日常学习方式,自学渠道和方式
- linux 状态码的意义,HTTP状态码是什么?常见的状态码描述都有什么?
- python3环境运行python2代码_使用Anaconda实现Python2和Python3共存及相互转换
- tensorflowgpu利用率为0_直流电压利用率的提高方法-梯形波调制法