二次剩余

对于素数 ppp 和数 aaa,满足 (a,p)=1(a,p)=1(a,p)=1。(注意 aaa 不一定小于 ppp)

若 ∃xx2≡a(modp)\exist_{x}\ x^2\equiv a\pmod p∃x​ x2≡a(modp),则称 aaa 是模 ppp 意义下的二次剩余,xxx 称为该二次剩余方程式的解。

否则称 aaa 是模 ppp 意义下的非二次剩余。

特判掉 p=2p=2p=2 的情况,接下来默认 ppp 均为非 222 质数,即奇素数。

勒让德符号

定义:
(ap)={0p∣a1a在(modp)意义下是二次剩余−1a在(modp)意义下不是二次剩余\Big(\frac{a}{p}\Big)= \begin{cases} 0\quad\quad\quad p\ \big|\ a\\ 1\quad\quad\quad a在\pmod p意义下是二次剩余\\ -1\quad\quad\ a在\pmod p意义下不是二次剩余 \end{cases} (pa​)=⎩⎪⎨⎪⎧​0p ∣∣​ a1a在(modp)意义下是二次剩余−1 a在(modp)意义下不是二次剩余​

欧拉准则

(ap)≡ap−12(modp)\Big(\frac ap\Big)\equiv a^{\frac{p-1}2}\pmod p (pa​)≡a2p−1​(modp)

证明:

  • p∣ap\ \big|\ ap ∣∣​ a。显然成立。

  • 当 aaa 是在模 ppp 意义下的二次剩余。

    即 ∃xx2≡a(modp)\exist_x\ x^2\equiv a\pmod p∃x​ x2≡a(modp)。

    有 (x2)p−12≡ap−12(modp)⇔xp−1≡ap−12(modp)(x^2)^\frac{p-1}2\equiv a^\frac{p-1}2\pmod p\Leftrightarrow x^{p-1}\equiv a^\frac{p-1}2\pmod p(x2)2p−1​≡a2p−1​(modp)⇔xp−1≡a2p−1​(modp)。

    ∵(a,p)=1∴(x,p)=1\because (a,p)=1\therefore(x,p)=1∵(a,p)=1∴(x,p)=1。

    ⇒xp−1≡1≡ap−12(modp)\Rightarrow x^{p-1}\equiv 1\equiv a^\frac{p-1}2\pmod p⇒xp−1≡1≡a2p−1​(modp)。

  • 当 aaa 在模 ppp 意义下不是二次剩余。

    则有 ∀i∈[1,p)ij≡a(modp)\forall_{i\in [1,p)}\ ij\equiv a\pmod p∀i∈[1,p)​ ij≡a(modp) 的 jjj 是唯一的,且 j≠ij\neq ij​=i。

    考虑用证明逆元唯一的思路来证明这里的唯一性。反证法。

    假设 0<j1<j2<p0<j_1<j_2<p0<j1​<j2​<p 满足 ij1≡ij2≡a(modp)ij_1\equiv ij_2\equiv a\pmod pij1​≡ij2​≡a(modp)。

    则 i(j2−j1)≡0(modp)⇒p∣i(j2−j1)i(j_2-j_1)\equiv 0\pmod p\Rightarrow p\ \big|\ i(j_2-j_1)i(j2​−j1​)≡0(modp)⇒p ∣∣​ i(j2​−j1​)。

    (i,p)=1⇒p∣(j2−j1)(i,p)=1\Rightarrow p\ \big|\ (j_2-j_1)(i,p)=1⇒p ∣∣​ (j2​−j1​),与 0<j2−j1<p⇒(j2−j1,p)=10<j_2-j_1<p\Rightarrow (j_2-j_1,p)=10<j2​−j1​<p⇒(j2​−j1​,p)=1 矛盾。

    p−1p-1p−1 是偶数,那么我们考虑可以把这些数两两配对,配出 p−12\frac{p-1}22p−1​ 对。

    即 ap−12≡(p−1)!≡−1(modp)a^\frac{p-1}2\equiv (p-1)!\equiv -1\pmod pa2p−1​≡(p−1)!≡−1(modp)(威尔逊定理)。


换言之:

x2≡a(modp),(a,p)=1x^2\equiv a\pmod p,(a,p)=1x2≡a(modp),(a,p)=1。

ap−12≡±1(modp)a^\frac{p-1}2\equiv \pm 1\pmod pa2p−1​≡±1(modp)。

方程有解当且仅当 ap−12≡1(modp)a^\frac{p-1}{2}\equiv 1\pmod pa2p−1​≡1(modp)。

Cipolla

lemma :设 ω\omegaω 不是模 ppp 的二次剩余,即 ̸∃xx2≡ω(modp)\not\exist_x\ x^2\equiv \omega\pmod p​∃x​ x2≡ω(modp),且 ω=t2−a\omega=t^2-aω=t2−a。则 x=(t+ω)p+12x=(t+\sqrt{\omega})^\frac{p+1}2x=(t+ω​)2p+1​ 是二次剩余方程 x2≡a(modp)x^2\equiv a\pmod px2≡a(modp) 的解。

证明:

(t+ω)p=∑i=0p(pi)ti(ω)p−i=tp+ωp2+∑i=1p−1(pi)ti(ω)p−i(t+\sqrt\omega)^p=\sum_{i=0}^{p}\binom pit^i(\sqrt\omega)^{p-i}=t^p+\omega^\frac{p}2+\sum_{i=1}^{p-1}\binom pit^i(\sqrt\omega)^{p-i}(t+ω​)p=∑i=0p​(ip​)ti(ω​)p−i=tp+ω2p​+∑i=1p−1​(ip​)ti(ω​)p−i。

i∈(0,p),(pi)=p!i!(p−i)!i\in(0,p),\binom{p}{i}=\frac{p!}{i!(p-i)!}i∈(0,p),(ip​)=i!(p−i)!p!​。

组合数是整数,i!,(p−i)!i!,(p-i)!i!,(p−i)! 里的每个数都 <p<p<p,又 ppp 是奇素数,所以 i!,(p−i)!i!,(p-i)!i!,(p−i)! 里面均不会筛到 ppp。

所以 p∣(pi)p\ \big|\ \binom pip ∣∣​ (ip​)。也就是说后面的求和在模 ppp 意义下是 000。

⇒(t+ω)p≡tp+(ω)p(modp)\Rightarrow (t+\sqrt\omega)^p\equiv t^p+(\sqrt\omega)^p\pmod p⇒(t+ω​)p≡tp+(ω​)p(modp)。

tp+(ω)p=tp+ωp−12ωt^p+(\sqrt\omega)^p=t^p+\omega^\frac{p-1}2\sqrt\omegatp+(ω​)p=tp+ω2p−1​ω​,因为 ω\omegaω 不是模 ppp 意义下的二次剩余,所以 (ωp)=−1=ωp−12\Big(\frac \omega p\Big)=-1=\omega^\frac{p-1}2(pω​)=−1=ω2p−1​,tp=tp−1t≡t(modp)t^p=t^{p-1}t\equiv t\pmod ptp=tp−1t≡t(modp)。

⇒(t+ω)p≡t−ω(modp)\Rightarrow (t+\sqrt\omega)^p\equiv t-\sqrt\omega\pmod p⇒(t+ω​)p≡t−ω​(modp)

x2≡(t+ω)p+1≡(t+ω)p(t+ω)≡(t−ω)(t+ω)≡t2−ω≡a(modp)x^2\equiv (t+\sqrt\omega)^{p+1}\equiv(t+\sqrt\omega)^p(t+\sqrt\omega)\equiv(t-\sqrt\omega)(t+\sqrt\omega)\equiv t^2-\omega\equiv a\pmod px2≡(t+ω​)p+1≡(t+ω​)p(t+ω​)≡(t−ω​)(t+ω​)≡t2−ω≡a(modp)。

在算法实现中,随机 ttt 后求 ω\omegaω,大约有一半的数都是非二次剩余。期望两次便可求出 xxx。


考虑另一种二次剩余方程:x2≡a(modpn)x^2\equiv a\pmod {p^n}x2≡a(modpn),其中 (a,p)=1(a,p)=1(a,p)=1,ppp 为奇质数。

先求出 x2≡a(modp)x^2\equiv a\pmod px2≡a(modp) 的一个解 τ\tauτ,有 τ2−a=kp⇒(τ2−a)n≡knpn≡0(modpn)\tau^2-a=kp\Rightarrow (\tau^2-a)^n\equiv k^np^n\equiv 0\pmod {p^n}τ2−a=kp⇒(τ2−a)n≡knpn≡0(modpn)。

{(r+a)n=f+ga(r−a)n=f−ga\begin{cases}(r+\sqrt a)^n=f+g\sqrt{a}\\(r-\sqrt a)^n=f-g\sqrt{a}\end{cases}{(r+a​)n=f+ga​(r−a​)n=f−ga​​

两个式子的结果答案长相一定可以这么写。

证明:二项式定理展开 (ni)τn−i(±a)i\binom ni\tau^{n-i}(\pm\sqrt{a})^i(in​)τn−i(±a​)i,(±a)i(\pm\sqrt{a})^i(±a​)i 如果 iii 是偶数,第 iii 项就在 fff 里面,否则就在 ggg 里面。

也就是说,(τ2−a)n≡[(τ+a)(τ−a)]n≡(τ+a)n(τ−a)n≡(f+ga)(f−ga)≡f2−g2a≡0(modpn)(\tau^2-a)^n\equiv [(\tau+a)(\tau-a)]^n\equiv(\tau+a)^n(\tau-a)^n\equiv(f+g\sqrt{a})(f-g\sqrt{a})\equiv f^2-g^2a\equiv 0\pmod {p^n}(τ2−a)n≡[(τ+a)(τ−a)]n≡(τ+a)n(τ−a)n≡(f+ga​)(f−ga​)≡f2−g2a≡0(modpn)。

(f,p)=1,(g,p)=1⇒f2inv(g2)≡a(modn)(f,p)=1,(g,p)=1\Rightarrow f^2\text{inv}(g^2)\equiv a\pmod n(f,p)=1,(g,p)=1⇒f2inv(g2)≡a(modn)。

由于 pnp^npn 不是质数,所以用 exgcd\text{exgcd}exgcd 求逆元即可。

代码

#include <cstdio>
#include <iostream>
#include <ctime>
#include <random>
using namespace std;
#define int long long
int T, n, p, omega;
mt19937 wwl(time(0));struct complex {int x, y;complex(){}complex( int X, int Y ) { x = X, y = Y; }complex operator * ( complex v ) {int ansx = ( x * v.x % p + y * v.y % p * omega % p ) % p;int ansy = ( x * v.y % p + y * v.x % p ) % p;return complex( ansx, ansy );}
};int qkpow( complex x, int y ) {complex ans( 1, 0 );while( y ) {if( y & 1 ) ans = ans * x;x = x * x;y >>= 1;}return ans.x;
}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 cipolla( int n, int p ) {n %= p;if( p == 2 ) return n;if( qkpow( n, p - 1 >> 1, p ) == p - 1 ) return -1;int t;while( 1 ) {t = wwl() % p;omega = ( ( t * t % p - n ) % p + p ) % p;if( qkpow( omega, p - 1 >> 1, p ) == p - 1 ) break;}complex ans( t, 1 );return qkpow( ans, p + 1 >> 1 );
}signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld %lld", &n, &p );if( n == 0 ) { puts("0"); continue; }int ans = cipolla( n, p );if( ! ~ ans ) { puts("Hola!"); continue; }if( ans == p - ans ) printf( "%lld\n", ans );else printf( "%lld %lld\n", min( ans, p - ans ), max( ans, p - ans ) );}return 0;
}

[学习笔记] 二次剩余相关推荐

  1. 多项式相关操作学习笔记

    多项式相关操作学习笔记 标签: 多项式 说在前边 记录一下相关的多项式操作,顺便存个模板.(多点求值之后的部分,有点写不动了...留坑留坑 多项式 定义 给定一个环\(R\)(\(R\)通常是交换环, ...

  2. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  3. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  4. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  5. 2020年Yann Lecun深度学习笔记(下)

    2020年Yann Lecun深度学习笔记(下)

  6. 2020年Yann Lecun深度学习笔记(上)

    2020年Yann Lecun深度学习笔记(上)

  7. 知识图谱学习笔记(1)

    知识图谱学习笔记第一部分,包含RDF介绍,以及Jena RDF API使用 知识图谱的基石:RDF RDF(Resource Description Framework),即资源描述框架,其本质是一个 ...

  8. 计算机基础知识第十讲,计算机文化基础(第十讲)学习笔记

    计算机文化基础(第十讲)学习笔记 采样和量化PictureElement Pixel(像素)(链接: 采样的实质就是要用多少点(这个点我们叫像素)来描述一张图像,比如,一幅420x570的图像,就表示 ...

  9. Go 学习推荐 —(Go by example 中文版、Go 构建 Web 应用、Go 学习笔记、Golang常见错误、Go 语言四十二章经、Go 语言高级编程)

    Go by example 中文版 Go 构建 Web 应用 Go 学习笔记:无痕 Go 标准库中文文档 Golang开发新手常犯的50个错误 50 Shades of Go: Traps, Gotc ...

最新文章

  1. 【微信小程序企业级开发教程】快递查询实例
  2. spi iic和串口的区别_GMII、SGMII和SerDes的区别和联系
  3. Android项目出现main.xml编译出错和 出现main.out.xml无法编译的解决办法
  4. android ListView详解
  5. 小程序使用vant-dialog组件内容出不来_微信官方小程序同构新方案Kbone全解析
  6. 行内元素中去掉文字的上下间距,使得文字所在元素的高度同字体高度一致的方法...
  7. pc模式 华为mate30_号称“重构想象”的华为Mate30系列,到底有多颠覆?一睹为快...
  8. python和json转换_【Python】python和json数据相互转换,json读取和写入,repr和eval()使用...
  9. Android 获取静态上下文(Application)
  10. mysql中出现乱码问题_Mysql中文乱码问题完美解决方案
  11. zip 后压缩包带路径
  12. python反编译软件下载_python批量反编译软件
  13. 常用的网站压力测试工具有哪些
  14. 飞思卡尔单片机CAN模块的物理特性的示波器观察
  15. selinux基本概念 | 开启selinux策略 | 安全上下文的临时修改 | 安全上下文的永久修改 | 如何修复selinux | selinux对服务功能的影响 | 系统自动排错
  16. 【错题】#10兰州烧饼——思考角度的转换
  17. mysql dba视频课_MySQL DBA专家
  18. Deferred异步操作
  19. [BJOI2019]勘破神机(斯特林数,数论)
  20. 更改sendmail附件大小限制

热门文章

  1. 深夜,学妹遇到了数据分析师生涯的第一个疑问
  2. 白话AI:看懂深度学习真的那么难吗?初中数学,就用10分钟
  3. 计算机科学中的虚拟化包括哪些,计算机虚拟化包括哪几个方面(计算机虚拟技术在计算机教学中的应用探究)...
  4. python总结函数图像_PIL使用小结(crop和paste函数)
  5. excel 如何替换带上标的文字_如何在Excel中批量提取中文汉字和英文字母
  6. php mysql explain_MySQL Explain详解
  7. camunda流程定义表无数据_[Python04] 学习snakemake,三步轻松搭建生信流程!
  8. java string底层实现_Java-学习日记(Shell与String底层原理)
  9. leetcote34. 在排序数组中查找元素的第一个和最后一个位置
  10. [SpringBoot2]原生组件注入_原生注解与Spring方式注入