二次剩余与高斯整数
C3H5ClO
2020-08-03 16:14:10
## 前置知识
1.基础的复数知识
2.基础的数论定理
3.一点点离散数学
4.一点点抽象代数(如果你只学算法,那么不用知道;如果想了解原理,可以去[维基百科](https://zh.wikipedia.org/))
## 观前提醒
本文含有大量数论知识和证明,萌新完全阅读需要至少1小时。全文的证明都加了引用,对证明不感兴趣的读者可以选择性跳过。
# 二次剩余
对于正整数 $n$,奇质数$p\nmid n$,如果存在正整数 $x$ 使 $x^2\equiv n\pmod{p}$,则 $n$ 为模 $p$ 的二次剩余。
以下的$a\equiv b$均指$a\equiv b\pmod{p}$。
定义勒让德符号$(\frac{n}{p})=\begin{cases}
1 & n是p的二次剩余\\
-1 & n不是p的二次剩余\\
0 & p|n
\end{cases}$
定理1:$(\frac{n}{p})\equiv n^{\frac{p-1}{2}}$。
>证明:
>
>1.若$n$是模$p$的二次剩余,则根据费马小定理,$n^{\frac{p-1}{2}}=(\sqrt n)^{p-1}\equiv1$
>
>2.若$n$不是模$p$的二次剩余,则根据扩展欧几里得算法,对于$i\in[1,p-1]$都有唯一的$j\in[1,p-1],i\neq j$满足$ij\equiv n$。这样的数对一共有$\frac{p-1}{2}$个,因此$n^{\frac{p-1}{2}}\equiv (p-1)!$。根据威尔逊定理,$(p-1)!\equiv-1$,那么$n^{\frac{p-1}{2}}\equiv-1$。
>
>3.若$p|n$,显然有$p|n^{\frac{p-1}{2}},n^{\frac{p-1}{2}}\equiv0$。
定理2:$[1,p-1]$中有$\frac{p-1}{2}$个二次剩余。
>证明:设$x,y\in[1,p-1],x\neq y,x^2\equiv y^2$,则$(x+y)(x-y)\equiv0$。由于$0<|x-y|<p$,必定是$x+y\equiv 0$。这样的数对$(x,y)$共有$\frac{p-1}{2}$个,因此共有$\frac{p-1}{2}$个二次剩余。
根据上述证明,发现剩余系中的二次剩余与实数的平方根具有统一性:要么没有;要么有一个平方根(0);要么有一对平方根,它们互为相反数。
## 求二次剩余的方法
问题:已知正整数$n,p$($p$为奇质数),求所有数$x$,使$x^2\equiv n$。[题目链接](https://www.luogu.com.cn/problem/P5491)
在$[0,p-1]$中随机产生一个数$a$,令$w=a^2-n$,若$(\frac{w}{p})=-1$,$(a+\sqrt w)^{\frac{p+1}{2}}$是$x$的一个解。
>证明:首先,显然有$\binom{p}{x}\equiv 0,x\in[1,p-1]$。因此,$(a+\sqrt w)^p=\sum_{i=0}^p\binom{p}{i}a^i(\sqrt w)^{p-i}\equiv a^p+(\sqrt w)^p$。根据费马小定理,$a^p\equiv a$。根据定理1,$(\sqrt w)^p=\sqrt ww^{\frac{p-1}{2}}\equiv -\sqrt w$。因此,$(a+\sqrt w)^{p+1}\equiv(a+\sqrt w)(a-\sqrt w)=a^2-w=n$
这里就出现了一个问题:$w$明明是非二次剩余,怎么还会有$\sqrt w$呢?这里我们需要用到扩域的思想。定义$\mathbb{Z}_p[\sqrt w]=\{a+b\sqrt w\mid a,b\in\mathbb{Z}\cap[0,p)\}$,根据$(a_1+b_1\sqrt w)(a_2+b_2\sqrt w)\%p=(a_1a_2+b_1b_2w)\%p+(a_1b_2+b_1a_2)\%p\sqrt w$,在$\mathbb{Z}_p[\sqrt w]$上定义乘法,可以实现快速幂。
由于$[1,p-1]$中有一半是二次剩余,因此随机的期望次数为2。这种做法可以求出一个二次剩余的解,另一个解是它的相反数。
代码如下:
```cpp
inline int ksm(int a,int b)
{
int c=1;
while(b){if(b&1)c=1ll*c*a%MOD; a=1ll*a*a%MOD; b>>=1;}
return c;
}
inline int lrd(int x){return ksm(x,MOD>>1);}//勒让德符号
struct cplx
{
int x,y;
inline friend cplx operator *(cplx a,cplx b)
{
return {(1ll*a.x*b.x+1ll*a.y*b.y%MOD*w)%MOD,(1ll*a.x*b.y+1ll*a.y*b.x)%MOD};
}
inline friend cplx operator ^(cplx a,int b)
{
cplx c={1,0};
while(b){if(b&1)c=c*a; a=a*a; b>>=1;}
return c;
}
}a;
void solve()
{
scanf("%d%d",&n,&MOD); n%=MOD;
x=lrd(n);
if(x==MOD-1)printf("Hola!\n");
else if(!x)printf("0\n");
else
{
x=rand()%(MOD-1)+1; w=(1ll*x*x-n+MOD)%MOD;
while(lrd(w)<=1)x=rand()%MOD,w=(1ll*x*x-n+MOD)%MOD;
a={x,1}; a=a^(MOD+1>>1);
ans1=a.x; ans2=MOD-a.x; if(ans1>ans2)swap(ans1,ans2);
printf("%d %d\n",ans1,ans2);
}
}
```
# 高斯整数
高斯整数集合$\mathbb{Z}[i]=\{a+bi\mid a,b\in\mathbb{Z}\}$,其中$i^2=-1$
几何意义:复平面上的整点
高斯整数环是欧几里得整环,同样满足裴蜀定理、欧几里得引理、唯一分解定理等基础的数论定理。
高斯整数的可逆元群$U(\mathbb{Z}[i])=\{1,i,-1,-i\}$。
高斯整数$u=a+bi$的共轭复数$\bar u=a-bi$,可逆元的共轭复数是可逆元。
性质:$\overline{u+v}=\bar u+\bar v,\overline{uv}=\bar u\bar v,\overline{\frac{u}{v}}=\frac{\bar u}{\bar v}$,直接展开即可证明。
高斯整数的范数$\|a+bi\|=a^2+b^2$,可逆元的范数为1。
性质:$\|ab\|=\|a\|\|b\|$,直接展开即可证明。
## 费马平方和定理
定理表述:奇质数能表示为两个平方数之和的充分必要条件是该质数被4除余1。
接下来给出欧拉对这个定理的证明。
>将可以表示为两个整数平方和的数定义为平方分解数。
>
>定理1:平方分解数的积是平方分解数。
>
>>证明:$(a^2+b^2)(p^2+q^2)=(ap+bq)^2+(aq-bp)^2=(ap-bq)^2+(aq+bp)^2$
>
>定理2:平方分解数被素平方分解数整除的商是平方分解数。
>
>>证明:$(ap+bq)(ap-bq)=a^2p^2-b^2q^2=a^2(p^2+q^2)-q^2(a^2+b^2)$
>>
>>由于$p^2+q^2|a^2+b^2$,因此$p^2+q^2|(ap+bq)(ap-bq)$。$p^2+q^2$是质数,则它整除其中一个因子,不妨设$p^2+q^2|ap+bq$,另一种情况同理。$(p^2+q^2)^2|(a^2+b^2)(p^2+q^2)=(ap+bq)^2+(aq-bp)^2$,则
>>有$(p^2+q^2)^2|(aq-bp)^2$,那么$p^2+q^2|aq-bp$
>>
>>因此,$\frac{a^2+b^2}{p^2+q^2}=\frac{(a^2+b^2)(p^2+q^2)}{(p^2+q^2)^2}=(\frac{ap+bq}{p^2+q^2})^2+(\frac{aq-bp}{p^2+q^2})^2$
>
>定理3:平方分解数被非平方分解数整除的商必有一个非平方分解因子。
>
>>证明:设$a=x\prod p_i$,$a$是平方分解数,$x$是非平方分解数。如果$p_i$均是平方分解数,根据定理2,用$p_i$一个个去除$a$,所得结果$x$也是平方分解数,与假设矛盾。
>
>定理4:如果$a$和$b$互素,则$a^2+b^2$的所有因子都是平方分解数。
>
>>这一步的证明运用了无穷递降法。
>>
>>证明:假设$x|a^2+b^2,a=mx+c,b=nx+d(c,d\in[-\frac{x}{2},\frac{x}{2}])$
>>
>>$a^2+b^2=(m^2+n^2)x^2+2(mc+nd)x+c^2+d^2$,则$x|c^2+d^2$。设$gcd(c,d)=g$,由于$a\perp b$,则$g\perp x$。设$e=\frac{c}{g},f=\frac{d}{g}$,则$x|e^2+f^2,e\perp f$。设$xy=e^2+f^2$,则$xy\le c^2+d^2\le(\frac{x}{2})^2+(\frac{x}{2})^2=\frac{x^2}{2},y\le \frac{x}{2}$。若$x$不是平方分解数,根据定理3,$y$必有一个非平方分解因子,设为$x'$,则$x'\le y\le \frac{x}{2}<x$。因此,如果存在一个非平方分解数$x$是一对互素数平方和的因数,就必定存在一个非平方分解数$x'<x$是另一对互素数平方和的因数。而正整数$x$不可能无穷减小,因此假设不成立,$x$必为平方分解数。
>
>定理5a:形为$4n+1$的素数是平方分解数。
>
>>证明:设$p=4n+1$。根据费马小定理,$\forall x\in[1,4n],p|x^{4n}-1$,则$p|(x+1)^{4n}-x^{4n}$,那么有$p|(x+1)^{2n}+x^{2n}$或$p|(x+1)^{2n}-x^{2n}$。假设$\exists x,p|(x+1)^{2n}+x^{2n}$,根据定理4,$p$是平方分解数。否则,$\forall x\in[1,4n],p|(x+1)^{2n}-x^{2n}=\Delta x^{2n}$,根据整除可加减的性质,$x^{2n}$的任意阶差分都可以被$p$整除。因此,$p|\Delta^{2n} x^{2n}=(2n)!$,而$p|(2n)!$显然不成立。因此这种情况不存在,$p$必为平方分解数。
>
>定理5a证明了充分性,还需要证明必要性。
>
>定理5b:形为$4n+3$的数不是平方分解数。
>
>>证明:完全平方数模4只可能为0或1,因此不存在两个完全平方数之和模4为3。
>
>至此,我们证明了费马平方和定理:奇质数是平方分解数的充分必要条件是该质数形为$4n+1$。
## 高斯素数
高斯整数环的素元称为高斯素数。
1.高斯素数的共轭复数是高斯素数。
> 证明:设$p$是高斯素数,$\bar p=uv,u,v\not\in U(\mathbb{Z}[i])$,则$p=\overline{uv}=\bar u\bar v$,与$p$是高斯素数矛盾。
2.$a+bi$是高斯素数当且仅当下列条件之一成立:
(1)$a,b$一个为0,另一个的绝对值为$4k+3$型素数。根据费马平方和定理,显然成立。
(2)$a^2+b^2$为$4k+1$型素数或$2$
>证明:设$u=a+bi,u\bar u=p$。设$u=de,1<\|d\|,\|e\|<\|u\|$。那么$p=u\bar u=de\bar d\bar e=(d\bar d)(e\bar e)$,其中$d\bar d,e\bar e$均为大于1的正整数,与$p$是质数矛盾。
## 定义带余除法
$a,b,q,r$均为高斯整数,$a=qb+r$,那么必定存在一组$q,r$使得$\|r\|\le \frac{1}{2}\|b\|$。我们把$q$称为$a$整除$b$的商,把$r$称为$a$整除$b$的余数。
>证明:假设$\frac{a}{b}=x+yi,q=x'+y'i$,其中 $x'=\lfloor x+\frac{1}{2}\rfloor,y'=\lfloor y+\frac{1}{2}\rfloor$,则有$|x-x'|\le\frac{1}{2},|y-y'|\le\frac{1}{2}$。
>$r=a-qb=b((x-x')+(y-y')i)$
>$\|(x-x')+(y-y')i\|=(x-x')^2+(y-y')^2\le\frac{1}{2}$
>$\|r\|=\|b\|\|(x-x')+(y-y')i\|\le\frac{1}{2}\|b\|$
上述证明同时也是求商和余数的算法。
因此,可以对两个高斯整数进行辗转相除法,算出它们的最大公因数。代码如下:
```cpp
inline cplx operator /(cplx a,cplx b)
{
double x=b.x*b.x+b.y*b.y;
return {round((a.x*b.x+a.y*b.y)/x),round((a.y*b.x-a.x*b.y)/x)};
}
inline cplx operator %(cplx a,cplx b){return a-a/b*b;}
inline cplx gcd(cplx a,cplx b)
{
while(b.x||b.y)a=a%b,swap(a,b);
return a;
}
```
## 分解4n+1型素数
[题目链接](https://loj.ac/problem/6465)
设$p=4n+1,p=u\bar u$。首先注意到$k^2\equiv-1\Leftrightarrow p|(k+i)(k-i)$,则$u=gcd(p,k+i)$。由于$[1,p-1]$中一半的数是二次剩余,随机一个$t\in[1,p-1]$使$t^{\frac{p-1}{2}}\equiv -1$,则$k=t^{\frac{p-1}{4}}=t^n$。随机成功概率为$\frac{1}{2}$,期望随机次数为2。
## 构造二平方和
问题:求$x^2+y^2=n$的所有整数解。
考虑将$n$分解为共轭复数的积,令$u=x+yi$,则$n=u\bar u$
1.将$n$在$\mathbb{R}$内质因数分解。
2.对$4n+3$型质数,若次数为偶数,则在$u$与$\bar u$中均分,只有1种分法;若次数为奇数,则不存在方案使$u$与$\bar u$共轭,方程无解。
3.将$4n+1$型质数分解。假设$p=v\bar v$,则$p^k=v^k\bar v^k$,为了让$u$与$\bar u$共轭,分配方案需要使分配给$u$与$\bar u$的$v$与$\bar v$次数之和相等,即将$v^i\bar v^{k-i}$分配给$u$,剩下的分配给$\bar u$,共有$k+1$种分法。
4.将$2$分解为$(1+i)(1-i)$。由于$\frac{1+i}{1-i}=i$,无论分配方案如何,分配给$u$与$\bar u$的都是$(1+i)^k$乘以可逆元,方案本质相同,因此随便怎么分配都一样,只有1种分法。
5.最终还可以将$u$分别乘以4个可逆元,得到$(x,y)(-x,-y)(-y,x)(y,-x)$4个解。
代码如下:
```cpp
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int z,p[105],a[105],cnt,x,y,ans1,ans2[1000005][2];
struct cplx
{
ll x,y;
inline friend cplx operator -(cplx a,cplx b){return {a.x-b.x,a.y-b.y};}
inline friend cplx operator *(cplx a,cplx b){return {a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};}
inline friend cplx operator /(cplx a,cplx b)
{
double x=b.x*b.x+b.y*b.y;
return {round((a.x*b.x+a.y*b.y)/x),round((a.y*b.x-a.x*b.y)/x)};
}
inline friend cplx operator %(cplx a,cplx b){return a-a/b*b;}
inline friend cplx operator ^(cplx a,int b)
{
cplx c={1,0};
while(b){if(b&1)c=c*a; a=a*a; b>>=1;}
return c;
}
}u1[105],u2[105],u;
inline cplx gcd(cplx a,cplx b)
{
while(b.x||b.y)a=a%b,swap(a,b);
return a;
}
inline int rand_int(){return rand()<<15^rand();}
inline int ksm(int a,int b,int MOD=1e9)
{
int c=1;
while(b){if(b&1)c=1ll*c*a%MOD; a=1ll*a*a%MOD; b>>=1;}
return c;
}
inline void addans(int x,int y){ans2[++ans1][0]=x; ans2[ans1][1]=y;}
void dfs(int step,cplx s)
{
if(step>cnt)
{
addans(s.x,s.y);
addans(-s.x,-s.y);
addans(-s.y,s.x);
addans(s.y,-s.x);
return;
}
if(p[step]==2||(p[step]&3)==3)dfs(step+1,s*u1[step]);
else
{
cplx x=u2[step]^a[step];
for(int i=0;i<=a[step];i++)dfs(step+1,s*x),x=x/u2[step]*u1[step];
}
}
int main()
{
scanf("%d",&z);
for(int i=2;i*i<=z;i++)
if(z%i==0)
{
p[++cnt]=i;
while(z%i==0)z/=i,a[cnt]++;
}
if(z>1)p[++cnt]=z,a[cnt]=1;
for(int i=1;i<=cnt;i++)
if(p[i]==2)u1[i]=(cplx){1,1}^a[i];
else if((p[i]&3)==1)
{
while(1)
{
x=rand_int()%(p[i]-1)+1;
if(ksm(x,p[i]>>1,p[i])==p[i]-1)break;
}
x=ksm(x,p[i]>>2,p[i]); u={p[i],0};
u1[i]=gcd(u,{x,1});
u2[i]=u/u1[i];
}
else if(a[i]&1){printf("0\n"); return 0;}
else u1[i]={ksm(p[i],a[i]>>1),0};
dfs(1,{1,0});
printf("%d\n",ans1);
for(int i=1;i<=ans1;i++)printf("%d %d\n",ans2[i][0],ans2[i][1]);
}
```
## 求平方分解方案数
令$f(n)=\sum_{i=1}^{\lfloor\sqrt n\rfloor}\sum_{j=0}^{\lfloor\sqrt n\rfloor}[i^2+j^2=n]$
则方案数为$4f(n)$。
根据构造二平方和的方法,$n$中每个素因子的方案可以分开考虑,因此$f(n)$是积性函数。其中:
$f(p^k)=\begin{cases}
1 & p=2\\
k+1 & p=4n+1\\
[k\%2=0] & p=4n+3
\end{cases}$
可以使用改动过的min25筛快速求前缀和。具体见[题目链接](https://loj.ac/problem/3069)
# 完结撒花!
### 参考资料
[维基百科](https://zh.wikipedia.org/)
[浅谈二次剩余](https://blog.csdn.net/stevensonson/article/details/85845334)
[高斯整数](https://www.cnblogs.com/tempestT/p/12288833.html)