前言
在有些时候,我们会需要求解这样的问题
x
2
≡
a
(
m
o
d
p
)
x^2\equiv a\pmod{p}
x2≡a(modp)
给定
a
a
a求是否有
x
x
x满足这个式子,若有r则称a是模p的二次剩余
若没有满足条件的
x
x
x,则称a是模p的非二次剩余
然而在一些题目中,我们既要判定它是否是模p的二次剩余,也要判断其值,本文就对此进行一些探究
对于所有模数
二次剩余数量
我们发现
a
2
≡
(
p
−
a
)
2
(
m
o
d
p
)
a^2\equiv (p-a)^2\pmod p
a2≡(p−a)2(modp)
所以满足条件的二次剩余数量不可能超过
⌊
n
2
⌋
+
1
\left\lfloor\frac n2\right\rfloor+1
⌊2n⌋+1
不同模数下的二次剩余
模数为偶质数
显然偶质数只有一个,那就是2
显然
0
0
0和
1
1
1都是
2
2
2的二次剩余
模数为奇质数
对于判定模数为奇素数时的情况
我们定义勒让德符号:
(
a
p
)
=
{
+
1
如
果
a
̸
≡
0
(
m
o
d
p
)
且
有
整
数
x
满
足
x
2
≡
a
(
m
o
d
p
)
−
1
如
果
没
有
整
数
x
满
足
x
2
≡
a
(
m
o
d
p
)
0
如
果
a
≡
0
(
m
o
d
p
)
\left(\frac ap\right)=\begin{cases}+1&如果a\not\equiv0\pmod p且有整数x满足x^2\equiv a\pmod p\\ -1&如果没有整数x满足x^2\equiv a\pmod p\\ 0&如果a\equiv0\pmod p \end{cases}
(pa)=⎩⎪⎨⎪⎧+1−10如果a̸≡0(modp)且有整数x满足x2≡a(modp)如果没有整数x满足x2≡a(modp)如果a≡0(modp)
我们先引入欧拉准则
这是一个用来判定的经典准则(其实勒让德符号的定义准确来说就是从这里定义的)
这里规定,当模数为奇素数的时候···(此处省略解释)
直接代入勒让德符号成为
(
a
p
)
=
a
p
−
1
2
(
m
o
d
p
)
\left(\frac ap\right)=a^{\frac{p-1}2}\pmod p
(pa)=a2p−1(modp)
口糊一下证明
由于模数是奇素数,所以我们就可以使用拉格朗日定理( k k k次多项式至多 k k k个根)
所以对于任意一个 a a a,满足 x 2 ≡ a ( m o d p ) x^2\equiv a\pmod p x2≡a(modp)的 x x x数量至多为 2 2 2
现在我们把 a = 0 a=0 a=0的情况扔掉,因为 a = 0 a=0 a=0显然满足上式
只考虑 a ≠ 0 a\neq0 a̸=0的情况
首先我们有费马小定理 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap−1≡1(modp)
由于 p p p是奇数,我们开始推式子
移项得
a p − 1 − 1 ≡ 0 ( m o d p ) a^{p-1}-1\equiv0\pmod p ap−1−1≡0(modp)
因式分解得
( a p − 1 2 − 1 ) ( a p − 1 2 + 1 ) ≡ 0 ( m o d p ) (a^{\frac{p-1}2}-1)(a^{\frac{p-1}2}+1)\equiv0\pmod p (a2p−1−1)(a2p−1+1)≡0(modp)
我们发现,如果有 x x x满足 x 2 ≡ a ( m o d p ) x^2\equiv a\pmod p x2≡a(modp),那么根据费马小定理 x p − 1 ≡ 1 ( m o d p ) x^{p-1}\equiv1\pmod p xp−1≡1(modp)
将 x x x用 a a a代替
a p − 1 2 ≡ 1 ( m o d p ) a^{\frac{p-1}2}\equiv1\pmod p a2p−1≡1(modp)
如果没有满足条件的 x x x,这说明
a p − 1 2 ̸ ≡ 1 ( m o d p ) a^{\frac{p-1}2}\not\equiv1\pmod p a2p−1̸≡1(modp)
则根据上面的方程,两项中至少有一项为 0 0 0
则 a p − 1 2 ≡ − 1 ( m o d p ) a^{\frac{p-1}2}\equiv-1\pmod p a2p−1≡−1(modp)
证毕
现在我们已经会如何判定了,然而OI中更多的是要求这个值(大雾)
假设我们现在已经判定完了,发现
a
a
a是模
p
p
p的二次剩余
我们现在要求
x
2
≡
a
(
m
o
d
p
)
x^2\equiv a\pmod p
x2≡a(modp)
移项得
a
−
1
x
2
≡
1
(
m
o
d
p
)
a^{-1}x^2\equiv 1\pmod p
a−1x2≡1(modp)
设
x
i
x_i
xi满足
(
a
−
1
x
i
2
)
2
i
≡
1
(
m
o
d
p
)
(a^{-1}x_i^2)^{2^i}\equiv 1\pmod p
(a−1xi2)2i≡1(modp)
我们发现
x
0
x_0
x0就是我们要求的值
我们提出
p
−
1
p-1
p−1所有的
2
2
2因子:
p
−
1
=
2
t
s
p-1=2^ts
p−1=2ts
我们得到一个已知的解了:
x
t
−
1
=
a
s
+
1
2
x_{t-1}=a^{\frac{s+1}2}
xt−1=a2s+1
为什么?
代入
(
a
−
1
x
t
−
1
2
)
2
t
−
1
≡
(
a
−
1
a
s
+
1
)
2
t
−
1
≡
a
2
t
−
1
s
≡
a
p
−
1
2
≡
1
(
m
o
d
p
)
(a^{-1}x_{t-1}^2)^{2^{t-1}}\equiv(a^{-1}a^{s+1})^{2^{t-1}}\equiv a^{2^{t-1}s}\equiv a^\frac{p-1}2\equiv1\pmod p
(a−1xt−12)2t−1≡(a−1as+1)2t−1≡a2t−1s≡a2p−1≡1(modp)
如果我们现在能够递推,那就能求答案了
首先我们发现
a
−
1
x
i
2
a^{-1}x_i^2
a−1xi2是模
p
p
p意义下的
2
t
2^t
2t阶单位根
设
a
−
1
x
i
2
=
ω
i
a^{-1}x_i^2=\omega_i
a−1xi2=ωi
我们现在已知
x
i
x_i
xi要递推求
x
i
−
1
x_{i-1}
xi−1
由于
ω
i
2
i
≡
1
(
m
o
d
p
)
\omega_i^{2^i}\equiv1\pmod p
ωi2i≡1(modp)
所以
ω
i
2
i
−
1
≡
±
1
(
m
o
d
p
)
\omega_i^{2^{i-1}}\equiv\pm1\pmod p
ωi2i−1≡±1(modp)
- 如果
ω
i
2
i
−
1
≡
1
(
m
o
d
p
)
\omega_i^{2^{i-1}}\equiv1\pmod p
ωi2i−1≡1(modp)
那么可以进行赋值 x i − 1 = x i x_{i-1}=x_i xi−1=xi
*如果 ω i 2 i − 1 ≡ − 1 ( m o d p ) \omega_i^{2^{i-1}}\equiv-1\pmod p ωi2i−1≡−1(modp)
我们现在要找一个 λ \lambda λ使得 x i − 1 = λ x i x_{i-1}=\lambda x_i xi−1=λxi并且满足条件 ( a − 1 ( λ x i ) 2 ) 2 i − 1 ≡ 1 ( m o d p ) (a^{-1}(\lambda x_i)^2)^{2^{i-1}}\equiv 1\pmod p (a−1(λxi)2)2i−1≡1(modp)
与式子 ( a − 1 x i 2 ) 2 i − 1 ≡ − 1 ( m o d p ) (a^{-1}x_i^2)^{2^{i-1}}\equiv -1\pmod p (a−1xi2)2i−1≡−1(modp)进行联立
得到 λ 2 i ≡ − 1 ( m o d p ) \lambda^{2^i}\equiv-1\pmod p λ2i≡−1(modp)
我们发现等于 − 1 -1 −1这个条件非常熟悉
对于一个非二次剩余 b b b, b p − 1 2 ≡ − 1 ( m o d p ) b^{\frac{p-1}2}\equiv-1\pmod p b2p−1≡−1(modp)
化一下式子成 − 1 ≡ b p − 1 2 ≡ b 2 t − 1 s ≡ ( b 2 t − i − 1 s ) 2 i -1\equiv b^{\frac{p-1}2}\equiv b^{2^{t-1}s}\equiv (b^{2^{t-i-1}s})2^i −1≡b2p−1≡b2t−1s≡(b2t−i−1s)2i
所以我们可以直接 λ = b 2 t − i − 1 s m o d    p \lambda=b^{2^{t-i-1}s}\mod p λ=b2t−i−1smodp
至于怎么找这个 b b b也非常简单,直接rand即可,由于非二次剩余占比为一半,即 T = 1 + T 2 T=1+\frac T2 T=1+2T即 T = 2 T=2 T=2,所以是 O ( 1 ) \mathcal O(1) O(1)的
该算法的总复杂度为 O ( l o g 2 p ) \mathcal O(log^2p) O(log2p)
贴出代码
const int mod=998244353;
template<typename T>
inline int pow(int x,T y)
{
rg int res=1;x%=mod;
for(;y;y>>=1,x=(ll)x*x%mod)if(y&1)res=(ll)res*x%mod;
return res;
}
inline int Quadratic_residue(const int a)
{
if(a==0)return 0;
int b=(rand()<<14^rand())%mod;
while(pow(b,(mod-1)>>1)!=mod-1)b=(rand()<<14^rand())%mod;
int s=mod-1,t=0,x,inv=pow(a,mod-2),f=1;
while(!(s&1))s>>=1,t++,f<<=1;
t--,x=pow(a,(s+1)>>1),f>>=1;
while(t)
{
f>>=1;
if(pow((int)((ll)inv*x%mod*x%mod),f)!=1)x=(ll)x*pow(b,s)%mod;
t--,s<<=1;
}
return min(x,mod-x);
}
先咕咕咕了,奇质数的比较常用,其它模数没用到所以暂时不写
贴个非常不错的博客的链接
我写这篇博客是因为我看不懂有些他写的内容+没有代码
很详细,感兴趣的可以点击看看