二次剩余
二次剩余,就是求解方程
此时\(p\)为一个奇素数,就是常规的二次剩余问题
根的数量
我们假设一个方程有多个根那么可以列出\(x_0^2\equiv x_1^2(\mod p)\)
移项之后可得\((x_1-x_0)(x_1+x_0)\equiv0(\mod p)\)
因为\(x_0\),\(x_1\)为两不同的根所以\(x_1-x_0\)模\(p\)不会为\(0\)
所以\(x_1+x_0\equiv0(\mod p)\),即\(x_0\),\(x_1\)为相反数
因为\(p\)为奇素数,所以两根肯定不相同,所以方程必然有两不同根
欧拉准则
那么我们现在解决判断\(n\)是否在模\(p\)的意义下为二次剩余的问题
先放结论\(n^{\frac{p-1}2}\equiv 1(\mod p)\)是\(n\)为模\(p\)意义下的二次剩余的充要条件
先证明必要性,由于\(n\)为二次剩余由\(x^{p-1}\equiv 1(\mod p)\)可知\((x^2)^{\frac{p-1}2}=n^{\frac{p-1}2}\equiv 1(\mod p)\)
再证明充分性,\(n=g^k\),其中\(g\)为原根,那么\(g^{k\frac{p-1}{2}}\equiv 1(\mod p)\),由于原根一定不为二次剩余,所以\(p-1|k\frac{p-1}2\)所以\(k\)必然为偶数,那么\(g^{\frac k2}\)即为\(n\)的二次剩余。
那么我们便证明了\(n^{\frac{p-1}2}\equiv 1(\mod p)\)与\(n\)为模\(p\)意义下的二次剩余是等价的
因为\(n^{p-1}\equiv 1(\mod p)\)所以\(n^{\frac{p-1}2}\)为\(1\)的二次剩余为\(1\)或\(-1\),所以若\(n\)是二次剩余,\(n^{\frac{p-1}2}\)的值为\(-1\)
Cipolla
我们现在考虑解方程\(x^2\equiv n\)
首先找到一个\(a\)满足\(a^2-n\)是非二次剩余,期望是\(2\)次即可找到
接下来定义\(i^2\equiv a^2-n\),这里的\(i\)的定义类似于单位虚数的定义。
然后可以把所有数表示为\(A+Bi\)的形式。
那么我们可以有两个结论
引理1:\(i^p\equiv-i\)
证明:\(i^p\equiv i(i^2)^{\frac{p-1}2}\equiv i(a^2-n)^{\frac{p-1}2}\equiv-i\)
引理2:\((A+B)^p\equiv A^p+B^p\)
证明:由二项式定理,由于\(p\)为质数,除了\(C_p^0\),\(C_p^p\)外的组合数分子上的阶乘没法消掉,模\(p\)为\(0\),只剩\(C_p^0A^p+C_p^pB^p\)
最后我们就可以得出结论\((a+i)^{p+1}\equiv n\)
证明:
那么\(\pm(a+i)^{\frac{p+1}2}\)就是方程的解
code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
struct Com{LL r,i;};
LL w;
Com mul(Com a,Com b,LL P){
Com c;
c.r=(a.r*b.r%P+a.i*b.i%P*w%P)%P;
c.i=(a.r*b.i%P+a.i*b.r%P)%P;
return c;
}
LL fpowr(LL a,LL b,LL P){LL ret=1;
for(;b;b>>=1,a=a*a%P)
if(b&1)ret=ret*a%P;
return ret;
}
Com fpowc(Com a,LL b,LL P){Com ret={1,0};
for(;b;b>>=1,a=mul(a,a,P))
if(b&1)ret=mul(ret,a,P);
return ret;
}
LL Euler(LL n,LL P){
return fpowr(n,P-1>>1,P);
}
LL solve(LL n,LL P){
n%=P;
LL a;do a=rand()%P;
while(Euler(w=(a*a%P-n+P)%P,P)!=P-1);
return fpowc({a,1},P+1>>1,P).r;
}
int main(){
srand(time(NULL));
int T;scanf("%d",&T);
while(T--){
LL n,P,a,b;
scanf("%lld%lld",&n,&P);
if(!n){puts("0");continue;}
if(Euler(n,P)==P-1){puts("Hola!");continue;}
else{
a=solve(n,P),b=P-a;
if(a>b)swap(a,b);
printf("%lld %lld\n",a,b);
}
}
return 0;
}

浙公网安备 33010602011771号