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

    二次剩余

    PS:以下内容大概都是抄的。
    大概是解这样一个方程:

    [x^2 equiv n pmod p ]

     
    这里讨论 (p) 为奇素数。

    称非 (0)(n) 是二次剩余当 (n) 存在上述方程的解,反之成为非二次剩余。

    二次剩余的数量为 (frac{p-1}{2}),原因是这样的:

    1.若一个数 (n) 为二次剩余,设它有两组解,(x_1,x_2)
    那么 (x_1^2 equiv x_2^2 equiv n),由平方差公式得到 ((x_1-x_2)(x_1+x_2) equiv 0)
    那么 (x_1 equiv -x_2),因为 (p) 为奇素数,所以 (x_1 eq x_2)

    2.若 (n) 为二次剩余,存在解 (x)(-x) 也为解。

    欧拉准则

    大概是判断一个数 (n) 是否是二次剩余。

    做法是这样的,求 (n^{frac{p-1}{2}}),若为 (1) 则是,否则不是。

    首先有这样一个事情,(n^{p-1} equiv 1),则 ((n^{frac{p-1}{2}})^2 equiv 1)
    若其取值为 (1),可以令 (n=g^k),其中 (g) 为原根。
    则有 (g^{kfrac{p-1}{2}} equiv 1),即 ((p-1)| kfrac{p-1}{2})
    (2|k),所以 (n) 为二次剩余。

    然后还有这样一个事情,若 (n) 为二次剩余,则存在 (x^2 equiv n)
    (n^{frac{p-1}{2}}equiv x^{p-1} equiv 1)
    所以 (n^{frac{p-1}{2}}equiv 1)(n) 是二次剩余是等价的条件。

    故可以通过 (n^{frac{p-1}{2}})(1)(-1) 来判断 (n) 是否为二次剩余。

    Cipolla

    大概是对于 (n) 为二次剩余,找到 (x) 满足 (x^2 equiv n)

    做法是这样的,首先找到一个 (a),满足 (a^2-n) 为非二次剩余,这个过程通过随机并检验即可实现。
    定义一个类似虚部的东西 (i),满足 (i^2 equiv a^2-n)
    然后有 ((a+i)^{p+1} equiv n)((a+i)^{frac{p+1}{2}}equiv x)

    有这样一些事情:

    1.((A+B)^p=A^p + B^p)
    通过二项式定理展开为 (sum limits_{j=0}^{p} A^j B^{p-j} inom{p}{j})
    其中 (inom{p}{j}) 中的质因子 (p) 只在 (j=0,j=p) 时不存在。

    [egin{align*} i^p&=i(i^2)^{frac{p-1}{2}}\ &=i(a^2-n)^{frac{p-1}{2}}\ &=-i\ end{align*}]

    这样的话考虑 ((a+i)^{p+1}) 这个东西。
    可以展开为 ((a+i)^p(a+i)=(a^p+i^p)(a+i)=(a-i)(a+i)=a^2-i^2=n)
    ((a+i)^{frac{p+1}{2}})(-(a+i)^{frac{p+1}{2}}) 是两个解。

    可以证明 ((a+i)^{frac{p+1}{2}}) 不存在虚部。
    假设虚部存在,则有 ((x+yi)^2=n,y eq 0)
    展开得 (x^2+y^2(a^2-n)-n=2xy)
    其中左侧不含虚部,故 (y eq 0,x=0)
    代入得到 (y^2i^2=n),显然无解,与假设不成立。
     
     

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int mod,n,a;
    struct node{
    	ll r,i;
    	node(int r=0,int i=0):r(r),i(i){}
    };
    inline node operator * (const node &x,const node &y){
    	return node((x.r*y.r%mod+x.i*y.i%mod*(1ll*a*a%mod-n+mod))%mod,(x.r*y.i+x.i*y.r)%mod);
    }
    inline ll qpow(ll x,int k,ll r=1){
    	for(;k;k>>=1,x=x*x%mod) if(k&1) r=r*x%mod;
    	return r;
    }
    inline node qpow(node x,int k,node r=node(1,0)){
    	for(;k;k>>=1,x=x*x) if(k&1) r=r*x;
    	return r;
    }
    bool check(int x){
    	return qpow(x,mod-1>>1)==1;
    }
    int main(){
    	int T; scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&mod);
    		if(!n){ puts("0"); continue; }
    		if(!check(n)){ puts("Hola!"); continue; }
    		for(a=rand()%(mod-1)+1;check((1ll*a*a-n+mod)%mod);a=rand()%(mod-1)+1);
    		int x=qpow(node(a,1),mod+1>>1).r,y=mod-x; if(y<x) swap(x,y);
    		printf("%d %d
    ",x,y);
    	}
    	return 0;
    }
  • 相关阅读:
    在TreeView控件节点中显示图片
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1145 Hashing
    PAT 甲级 1145 Hashing
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1149 Dangerous Goods Packaging
  • 原文地址:https://www.cnblogs.com/skyh/p/13357396.html
Copyright © 2011-2022 走看看