二次剩余小结

二次剩余

定义

对于模数\(n\)和整数\(a\),若存在整数\(x\),满足

\[x^2\equiv a(mod\ n) \]

则称\(x\)是模\(n\)意义下的二次剩余,否则是非二次剩余

注:这里讨论的\(x\)满足\(x\in[1,n)\)

判定

欧拉判别法:对于奇素数\(p\)\(a\)是模\(p\)意义下的二次剩余当且仅当\(a^{\frac{p-1}{2}}\equiv 1(mod\ p)\)

类似的,若\(a\)是模\(p\)意义下的二次非剩余则有\(a^{\frac{p-1}{2}}\equiv-1(mod\ p)\)

证明

先证明在\(a\nmid p\)时,\(a^{\frac{p-1}{2}}\equiv 1或-1(mod\ p)\)

由费马小定理知\(a^{p-1}\equiv 1(mod\ p)\)

移项,利用平方差公式得\((a^{\frac{p-1}{2}}+1)(a^{\frac{a-1}{2}}-1)\equiv 0(mod\ p)\)

再由\(p\)是奇素数知上两式中必有且仅有一个同余于0

再证明若\(a\)是二次剩余的充要条件为\(a^{\frac{p-1}{2}}\equiv 1(mod\ p)\)

先证必要性,若\(a\)是模\(p\)意义下的二次剩余,那么必有整数\(x_0^2\equiv a(mod\ p)\),且\(p\nmid x_0\)

同时做\(\frac{p-1}{2}\)次方,有\(a^{\frac{p-1}{2}}\equiv x_0^{p-1}\equiv 1(mod\ p)\)

再证充分性,设有\(a^{\frac{p-1}{2}}\equiv 1(mod\ p)\)

对于\([1,p)\)中的整数,考虑如下的同余方程

\[xy\equiv a(mod\ p) \]

注意到,对于任意的整数\(x\in[1,p)\),一定有且仅有一个\(y\in[1,p)\)满足上式

假设\(a\)不是二次剩余,那么对\(\forall x\),均有\(y\neq x\)

也就是说对于\([1,p)\)中的\(p-1\)个整数,我们可以将它们分成\(\frac{p-1}{2}\)组,使得每一个数均正好属于一组

将这\(p-1\)个数乘起来,有

\[(p-1)!~\equiv a^{\frac{p-1}{2}}(mod\ p) \]

由威尔逊定理,有\((p-1)!\equiv -1(mod\ p)\),也就是\(a^{\frac{p-1}{2}}\equiv -1(mod\ p)\),与题设矛盾

故假设错误,所以一定有\(a\)是模\(p\)意义下的二次剩余

勒让德(Legendre)符号

方便描述,我们定义勒让德(Legendre)符号\(\begin{pmatrix}\frac{n}{p}\end{pmatrix}\)

\[\begin{pmatrix}\frac{n}{p}\end{pmatrix}= \begin{cases} 0 & a|p\\ -1 & a不是模p意义下的二次剩余\\ 1 & a是模p意义下的二次剩余 \end{cases} \]

具体求值的话可以利用上面的欧拉判别法(仅当\(p\)是奇素数时)

求解

先证明一个定理:

在模\(p\)意义下的一个简化剩余系中,有\(\frac{p-1}{2}\)个数具有二次剩余,且一个模\(p\)意义下的二次剩余\(a\),有两个不同的\(x\)满足\(x^2\equiv a(mod\ p)\)

证明

取模\(p\)意义下的一个简化剩余系如下

\[-\frac{p-1}{2},-\frac{p-1}{2}+1,\cdots,-1,1,2,\cdots,\frac{p-1}{2} \]

\(a\)是模\(p\)意义下的二次剩余,仅当

\[a\equiv(-\frac{p-1}{2})^2或(-\frac{p-1}{2}+1)^2\cdots或(\frac{p-1}{2})^2(mod\ p) \]

又由\((-x)^2=x^2\)知,若\(a\)是模\(p\)意义下的二次剩余,仅当

\[a\equiv 1^2或2^2或\cdots或(\frac{p-1}{2})^2(mod\ p) \]

且我们知道在\(1\leq i<j\leq \frac{p-1}{2}\)时,\(i^2\)\(j^2\)在模\(p\)意义下不相等,所以上面给出的\(\frac{p-1}{2}\)个数的平方恰好对应了在模\(p\)的意义下有二次剩余的\(\frac{p-1}{2}\)个不同的数,所以在模\(p\)的意义下\(p\)的简化剩余系中有\(\frac{p-1}{2}\)个数有二次剩余

根据上面的证明,对于一个二次剩余\(a\),那么一定存在\(x\in[1,\frac{p-1}{2}]\),使得\(x^2\equiv a(mod\ p)\)

那么在一开始提到的简化剩余系中,一定还有一个\(-x\)使得\((-x)^2\equiv a(mod\ p)\)

于是就有两个不同的\(x\)使得\(x^2\equiv a(mod\ p)\)

那么这和求解有什么关系呢?

首先判掉不是二次剩余的情况

接下来有2个\(x\)满足\(x^2\equiv a(mod\ p)\),我们只需要求出一个,由上面的证明知另一个和它的和为\(p\)

(接下来介绍高端操作)

假设我们要求\(x^2\equiv n(mod\ p)\),其中\(p\)是一个奇素数

我们先随便找一个数\(a\),满足\(\begin{pmatrix}\frac{a^2-n}{p} \end{pmatrix}=-1\)

\(\omega=\sqrt{a^2-n}\),那么\(x=(a+\omega)^\frac{p+1}{2}\)

正确性呢?

证明

\(x^2=(a+\omega)^{p+1}=(a+\omega)^p(a+\omega)=(a+\omega)\sum_{i=0}^p\dbinom{p}{i}a^i\omega^{p-i}\)

注意到\(1\leq i<p\)时,\(p|\dbinom{p}{i}\)

于是\(x^2\equiv(a^p+\omega^p)(a+w)\ (mod\ p)\)

我们由费马小定理知\(a^{p-1}\equiv 1(mod\ p)\),所以\(a^p\equiv a(mod\ p)\)

那这个\(\omega^p\)是什么,他甚至可能不是整数

我们由上面的操作过程知\(\omega^{p-1}=(\omega^2)^{\frac{p-1}{2}}\equiv(a^2-n)^{\frac{p-1}{2}}\equiv -1(mod\ p)\)

所以\(\omega^p\equiv -\omega(mod\ p)\)

于是\(x^2\equiv(a-\omega)(a+\omega)\equiv a^2-(a^2-n)\equiv n(mod\ p)\)

证毕

然后你就会发现这个做法的时间复杂度和找\(a\)所花的时间有关

然而你由上面的证明过程知你有\(\frac{1}{2}\)的几率找到一个合法的\(a\)

然后就做完了?这个\(\omega\)可以是无理数!

仿照复数\(a+bi\)的形式,我们将所有数写成\(a+b\omega\),这里的话重新写一个乘法就可以了

模板题:http://acm.timus.ru/problem.aspx?space=1&num=1132

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define fir first
#define sec second
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define maxd 1000000007
#define eps 1e-6
typedef long long ll;
const int N=100000;
const double pi=acos(-1.0);
ll w,p,n;
struct Complex{
	ll x,y;
	Complex(ll _x=0,ll _y=0) {x=_x;y=_y;}
};
Complex operator *(Complex a,Complex b) 
{
	return Complex((a.x*b.x%p+a.y*b.y%p*w%p)%p,(a.x*b.y+a.y*b.x)%p);
}
ll qpow(ll x,ll y,ll p)
{
	ll ans=1;
	while (y)
	{
		if (y&1) ans=ans*x%p;
		x=x*x%p;
		y>>=1;
	}
	return ans;
}

Complex qpow(Complex a,ll y)
{
	Complex ans=Complex(1,0);
	while (y)
	{
		if (y&1) ans=ans*a;
		a=a*a;
		y>>=1;
	}
	return ans;
}

int read()
{
	int x=0,f=1;char ch=getchar();
	while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
	while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
	return x*f;
}

ll Legendre(ll x)
{
	return qpow(x,(p-1)>>1,p);
}

int main()
{
	srand(19260817);
	int T=read();
	while (T--)
	{
		scanf("%lld%lld",&n,&p);
		if (p==2) puts("1");
		else
		{
			if (Legendre(n)+1==p) puts("No root");
			else
			{
				ll a;
				while (1)
				{
					a=rand()%p;
					w=((a*a-n)%p+p)%p;
					if (Legendre(w)+1==p) break; 
					//cout << Legendre(w) << " " << w << endl;
					//system("pause");
				}
				ll ans1=qpow(Complex(a,1),(p+1)>>1).x;
				ll ans2=p-ans1;
				if (ans1>ans2) swap(ans1,ans2);
				printf("%lld %lld\n",ans1,ans2);
			}
		}
	}
	return 0;
}
posted @ 2019-05-23 15:56  EncodeTalker  阅读(287)  评论(0编辑  收藏  举报