zoukankan      html  css  js  c++  java
  • 二次剩余小结

    二次剩余

    定义

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

    [x^2equiv a(mod n) ]

    则称(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))中的整数,考虑如下的同余方程

    [xyequiv a(mod 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 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)符号(egin{pmatrix}frac{n}{p}end{pmatrix})

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

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

    求解

    先证明一个定理:

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

    证明

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

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

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

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

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

    [aequiv 1^2或2^2或cdots或(frac{p-1}{2})^2(mod 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;
    }
    
  • 相关阅读:
    python递归可视化
    python递归基础
    python之双端队列及回文检测
    python接口多线程压测
    python获取文件目录下文件名并修改名称
    Linux 截取日志命令
    python计算后续表达式
    python十进制数转换成任意进制数
    python|os库
    python|英文标题格式化
  • 原文地址:https://www.cnblogs.com/encodetalker/p/10912415.html
Copyright © 2011-2022 走看看