二次剩余
定义
对于模数(n)和整数(a),若存在整数(x),满足
则称(x)是模(n)意义下的二次剩余,否则是非二次剩余
注:这里讨论的(x)满足(xin[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 mid 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^2equiv a(mod p)),且(p mid 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))中的整数,考虑如下的同余方程
注意到,对于任意的整数(xin[1,p)),一定有且仅有一个(yin[1,p))满足上式
假设(a)不是二次剩余,那么对(forall x),均有(y eq x)
也就是说对于([1,p))中的(p-1)个整数,我们可以将它们分成(frac{p-1}{2})组,使得每一个数均正好属于一组
将这(p-1)个数乘起来,有
由威尔逊定理,有((p-1)!equiv -1(mod p)),也就是(a^{frac{p-1}{2}}equiv -1(mod p)),与题设矛盾
故假设错误,所以一定有(a)是模(p)意义下的二次剩余
勒让德(Legendre)符号
方便描述,我们定义勒让德(Legendre)符号(egin{pmatrix}frac{n}{p}end{pmatrix})
具体求值的话可以利用上面的欧拉判别法(仅当(p)是奇素数时)
求解
先证明一个定理:
在模(p)意义下的一个简化剩余系中,有(frac{p-1}{2})个数具有二次剩余,且一个模(p)意义下的二次剩余(a),有两个不同的(x)满足(x^2equiv a(mod p))
证明
取模(p)意义下的一个简化剩余系如下
若(a)是模(p)意义下的二次剩余,仅当
又由((-x)^2=x^2)知,若(a)是模(p)意义下的二次剩余,仅当
且我们知道在(1leq i<jleq 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),那么一定存在(xin[1,frac{p-1}{2}]),使得(x^2equiv a(mod p))
那么在一开始提到的简化剩余系中,一定还有一个(-x)使得((-x)^2equiv a(mod p))
于是就有两个不同的(x)使得(x^2equiv a(mod p))
那么这和求解有什么关系呢?
首先判掉不是二次剩余的情况
接下来有2个(x)满足(x^2equiv a(mod p)),我们只需要求出一个,由上面的证明知另一个和它的和为(p)
(接下来介绍高端操作)
假设我们要求(x^2equiv n(mod p)),其中(p)是一个奇素数
我们先随便找一个数(a),满足(egin{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}^pdbinom{p}{i}a^iomega^{p-i})
注意到(1leq i<p)时,(p|dbinom{p}{i})
于是(x^2equiv(a^p+omega^p)(a+w) (mod p))
我们由费马小定理知(a^{p-1}equiv 1(mod p)),所以(a^pequiv 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^pequiv -omega(mod p))
于是(x^2equiv(a-omega)(a+omega)equiv a^2-(a^2-n)equiv n(mod p))
证毕
然后你就会发现这个做法的时间复杂度和找(a)所花的时间有关
然而你由上面的证明过程知你有(frac{1}{2})的几率找到一个合法的(a)
然后就做完了?这个(omega)可以是无理数!
仿照复数(a+bi)的形式,我们将所有数写成(a+bomega),这里的话重新写一个乘法就可以了
模板题: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
",ans1,ans2);
}
}
}
return 0;
}