二次剩余

https://blog.csdn.net/acdreamers/article/details/10182281
http://blog.miskcoo.com/2014/08/quadratic-residue
对于奇素数 p m o d    4 = 3 p\mod 4 = 3 pmod4=3 n ≡ n p + 1 4 ( m o d p ) \sqrt n\equiv n^{\frac {p+1}4}\pmod p n n4p+1(modp)
对于(任意)奇素数 p p p可以找一个非二次剩余(用随机方法找) ω ≡ a 2 − n ( m o d p ) \omega \equiv a^2-n\pmod p ωa2n(modp)
那么 n ≡ ( a + ω ) p + 1 2 ( m o d p ) \sqrt n\equiv(a+\sqrt\omega)^{\frac {p+1}2}\pmod p n (a+ω )2p+1(modp)

( a + ω ) p + 1 2 ≡ ( a + ω ) ( a + ω ) p (a+\sqrt \omega)^{\frac {p+1}2} \equiv \sqrt{(a+\sqrt \omega)(a+\sqrt \omega)^p} (a+ω )2p+1(a+ω )(a+ω )p
( a + ω ) p = ∑ i = 0 p ( p i ) a i ( ω ) p − i ≡ ( p 0 ) ( ω ) p + ( p p ) a p ≡ ω p − 1 2 ω + a ≡ a − ω ( m o d p ) (a+\sqrt \omega)^p=\sum_{i=0}^p\binom{p}{i}a^i(\sqrt \omega) ^{p-i}\equiv \binom p0(\sqrt \omega)^p + \binom ppa^p\equiv \omega^{\frac {p-1}2}\sqrt \omega + a\equiv a-\sqrt \omega \pmod p (a+ω )p=i=0p(ip)ai(ω )pi(0p)(ω )p+(pp)apω2p1ω +aaω (modp)
( a + ω ) p + 1 2 ≡ ( a + ω ) ( a − ω ) ≡ a 2 − ω ≡ n ( m o d p ) (a+\sqrt \omega)^{\frac {p+1}2}\equiv \sqrt{(a+\sqrt \omega)(a-\sqrt \omega)} \equiv \sqrt{a^2-\omega} \equiv \sqrt{n}\pmod p (a+ω )2p+1(a+ω )(aω ) a2ω n (modp)

Luogu模板cipolla:
AC Code:

#include
using namespace std;

int mod,n;

int Pow(int base,int k){
	int ret = 1;
	for(;k;k>>=1,base=1ll*base*base%mod)
		if(k&1)
			ret=1ll*ret*base%mod;
	return ret;
}

int w;
struct cplx{
	int r,i;
	cplx(int r=0,int i=0):r(r),i(i){}
	cplx operator *(const cplx &B)const{ return cplx((1ll*r*B.r+1ll*i*B.i%mod*w)%mod,(1ll*i*B.r+1ll*r*B.i)%mod); } 
}A;

cplx Pow(cplx base,int k){
	cplx ret = 1;
	for(;k;k>>=1,base=base*base)
		if(k&1)
			ret=ret*base;
	return ret;
}

int main(){
	int T;
	for(scanf("%d",&T);T--;){
		scanf("%d%d",&n,&mod);
		
		if(n == 0){
			puts("0");
			continue;
		}
		
		srand(19260817);
		int a = 0;
		do{
			a = rand() % (mod-1) + 1;
			w = ((1ll * a * a - n) % mod + mod) % mod; 
		}while(Pow(w,(mod-1)/2) == 1);
		A = Pow(cplx(a , 1) , (mod+1)/2);
		
		if(A.i) puts("Hola!");
		else{
			vector<int>ans;
			ans.push_back((A.r+mod)%mod);
			ans.push_back((mod-A.r)%mod);
			sort(ans.begin(),ans.end());
			ans.resize(unique(ans.begin(),ans.end())-ans.begin());
			for(int i=0;i<ans.size();i++)
				printf("%d%c",ans[i]," \n"[i==ans.size()-1]);
		}
	}
}

对于奇素数的幂 p q p^q pq,先求出 t ≡ n ( m o d p ) t \equiv \sqrt n \pmod p tn (modp)
那么 t 2 − n ≡ 0 ( m o d p ) t^2-n\equiv 0\pmod p t2n0(modp)
( t 2 − n ) q ≡ 0 ( m o d p q ) (t^2-n)^q\equiv 0\pmod {p^q} (t2n)q0(modpq)
( t − n ) q ( t + n ) q ≡ 0 ( m o d p q ) (t-\sqrt n)^q(t+\sqrt n)^q\equiv 0\pmod {p^q} (tn )q(t+n )q0(modpq)
可以发现若设 ( t + n ) q = a + b n (t+\sqrt n)^q = a + b\sqrt n (t+n )q=a+bn
( t − n ) q = a − b n (t-\sqrt n)^q = a - b\sqrt n (tn )q=abn
那么 ( t 2 − n ) q = a 2 − b 2 n ≡ 0 ( m o d p q ) (t^2-n)^q = a^2-b^2n \equiv 0\pmod {p^q} (t2n)q=a2b2n0(modpq)
那么就可以发现 n ≡ a b ( m o d p q ) \sqrt n \equiv \frac ab \pmod{p^q} n ba(modpq),直接在这个域内算就行了。

你可能感兴趣的:(模板,数论)