二次剩余

引言

我们在研究多项式开根的时候,想到了一个问题,若常数项不为1,那么怎么开根呢?
这就涉及到二次剩余。
那么什么是二次剩余呢?若在模ppp意义下,存在一个xxx,使得x2≡a(modp)x^2 \equiv a \pmod{p}x2a(modp),则称aaaxxx关于ppp的二次剩余。若不存在这样的xxx,则称aaa为非二次剩余。
现在我们知道了aaa,要求解xxx,怎么办呢?

p为奇素数

首先引入欧拉准则
aaa为模ppp意义下的二次剩余时,ap−12≡1(modp)a^{\frac{p-1}{2}} \equiv 1 \pmod{p}a2p11(modp)
aaa为模ppp意义下的非二次剩余时,ap−12≡p−1(modp)a^{\frac{p-1}{2}} \equiv p-1 \pmod{p}a2p1p1(modp)
我们要求的xxx满足:(a−1x2)20≡1(modp)(a^{-1}x^2)^{2^0} \equiv 1 \pmod{p}(a1x2)201(modp)
p−1=s2tp-1=s2^tp1=s2t,设xt−1=as+12x _ {t-1}=a^{\frac{s+1}{2}}xt1=a2s+1,那么根据欧拉准则第一条,有:(a−1xt−12)2t−1≡1(modp)(a^{-1}x_{t-1}^2)^{2^{t-1}} \equiv 1 \pmod{p}(a1xt12)2t11(modp)
诶…要不我们设(a−1xt−k2)2t−k≡1(modp)(a^{-1}x _ {t-k}^2)^{2^{t-k}} \equiv 1 \pmod{p}(a1xtk2)2tk1(modp),这样我们要求的就是x0x_0x0
思考如何从xt−kx _ {t-k}xtk推到xt−k−1x _ {t-k-1}xtk1
et−k=a−1xt−k2e _ {t-k}=a^{-1}x _ {t-k}^2etk=a1xtk2
et−k2t−k−1≡1(modp)e _ {t-k}^{2^{t-k-1}} \equiv 1 \pmod{p}etk2tk11(modp)(即将et−k2t−ke _ {t-k}^{2^{t-k}}etk2tk开根),显然xt−k−1=xt−kx _ {t-k-1}=x _ {t-k}xtk1=xtk
et−k2t−k−1≡p−1(modp)e _ {t-k}^{2^{t-k-1}} \equiv p-1 \pmod{p}etk2tk1p1(modp)。我们试图让xt−kx _ {t-k}xtk乘一个值使得它变成xt−k−1x _ {t-k-1}xtk1。那么想到欧拉准则的第二条,首先随机一个非二次剩余bbb,然后发现(b2k−1s)2t−k≡p−1(modp)(b^{2^{k-1}s})^{2^{t-k}} \equiv p-1 \pmod{p}(b2k1s)2tkp1(modp),所以b2k−1sb^{2^{k-1}s}b2k1s是我们满足条件的值,此时让xt−k−1=b2k−1sxt−kx _ {t-k-1}=b^{2^{k-1}s}x _ {t-k}xtk1=b2k1sxtk即可。
最后x0x_0x0其实有正负两个解,都满足条件。
例题:URAL 1132
代码:

#include<bits/stdc++.h>
using namespace std;
#define RI register int
int read() {
	int q=0;char ch=' ';
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') q=q*10+ch-'0',ch=getchar();
	return q;
}
int T,a,p,bin[22];
int ksm(int x,int y,int p) {
	int re=1;
	for(;y;y>>=1,x=1LL*x*x%p) if(y&1) re=1LL*re*x%p;
	return re;
}
int jud(int x,int p) {return ksm(x,(p-1)/2,p)==1;}
void work() {
	int s=p-1,b,t=0;
	while(!(s&1)) ++t,s>>=1;
	int inva=ksm(a,p-2,p),e=ksm(a,s,p),x=ksm(a,(s+1)/2,p);
	while("xzy is too strong") {
		b=rand()%p+1,b=((b*b-a)%p+p)%p;
		if(b&&!jud(b,p)) break;
	}
	for(RI k=1;k<t;++k)
		if(ksm(e,bin[t-k-1],p)!=1)
			x=1LL*x*ksm(b,bin[k-1]*s,p)%p,e=1LL*inva*x%p*x%p;
	int x1=x,x2=p-x;
	if(x1>x2) swap(x1,x2);
	printf("%d %d\n",x1,x2);
}
int main()
{
	srand(19260817);
	T=read();
	bin[0]=1;for(RI i=1;i<=20;++i) bin[i]=bin[i-1]<<1;
	while(T--) {
		a=read(),p=read();
		if(p==2) {puts("1");continue;}
		if(!jud(a,p)) {puts("No root");continue;}
		work();
	}
    return 0;
}

p为奇素数的幂

求满足x2≡a(modpq)x^2 \equiv a \pmod{p^q}x2a(modpq)xxx
a=pkda=p^kda=pkd
显然答案是x=pk2x0x=p^{\frac{k}{2}}x_0x=p2kx0的形式。
pkx02≡pkd(modpq)p^k x _ 0^2 \equiv p^k d \pmod{p^q}pkx02pkd(modpq),也就是说(d−x02)pk≡0(modpq)(d-x _ 0^2)p^k \equiv 0 \pmod{p^q}(dx02)pk0(modpq),那么有(d−x02)≡0(modpq−k)(d-x _ 0^2) \equiv 0 \pmod{p^{q-k}}(dx02)0(modpqk)
问题转化为求x02≡d(modpq−k)x _ 0^2 \equiv d \pmod{p^{q-k}}x02d(modpqk),而dddppp是互质的。
为了方便起见,假设我们现在要求解的问题是x2≡a(modpq)x^2 \equiv a \pmod{p^q}x2a(modpq)aaappp互质。

找到一个模pqp^qpq的简化剩余系下的原根ggg,我们就可以用gr(1≤r≤ϕ(pq))g^r(1 \leq r \leq \phi(p^q))gr(1rϕ(pq))来表示所有在模pqp^qpq意义下与pqp^qpq互质的数。
rrr为奇数时,设存在gr≡g2m(modpq)g^r \equiv g^{2m} \pmod{p^q}grg2m(modpq)。也就是r≡2m(modϕ(pq))r \equiv 2m \pmod{\phi(p^q)}r2m(modϕ(pq)),也就是r=2m+kϕ(pq)r=2m+k\phi(p^q)r=2m+kϕ(pq)
我们知道ϕ(pq)=(p−1)pq−1\phi(p^q)=(p-1)p^{q-1}ϕ(pq)=(p1)pq1,又因为ppp是奇素数,所以ϕ(pq)\phi(p^q)ϕ(pq)是偶数,所以2m+kϕ(pq)2m+k\phi(p^q)2m+kϕ(pq)也是偶数。而rrr是奇数,所以显然找不到这样的mmm
当然因为ggg肯定是与ppp互质的,所以gr≡g2mpt(modpq)g^r \equiv g^{2m}p^t \pmod{p^q}grg2mpt(modpq)也是不可能成立的啦。所以此时grg^rgr是个二次非剩余啦。
而当rrr为偶数的时候,显然grg^rgr是个二次剩余啦。

对于任意二次剩余g2kg^{2k}g2k,有
(g2k)ϕ(pq)2=(gk)ϕ(pq)≡1(modpq)(g^{2k})^{\frac{\phi(p^q)}{2}} = (g^k)^{\phi(p^q)} \equiv 1 \pmod{p^q}(g2k)2ϕ(pq)=(gk)ϕ(pq)1(modpq)
对于任意二次非剩余g2k+1g^{2k+1}g2k+1有:
(g2k+1)ϕ(pq)2≡gϕ(pq)2(mod()pq)(g^{2k+1})^{\frac{\phi(p^q)}{2}} \equiv g^{\frac{\phi(p^q)}{2}} \pmod(p^q)(g2k+1)2ϕ(pq)g2ϕ(pq)(mod()pq)
我们知道gϕ(pq)2g^{\frac{\phi(p^q)}{2}}g2ϕ(pq)gϕ(pq)g^{\phi(p^q)}gϕ(pq)肯定不相等,而后者等于1,前者是后者的开根,所以等于-1。
我们得到了一个new欧拉准则。
求解时,先将问题转化为aaappp互质,然后令ϕ(pq)=s2t\phi(p^q)=s2^tϕ(pq)=s2t,套用p为奇素数时的求解方法即可。

p为2的幂

这个嘛…同样,化一下,令a=2kda=2^kda=2kd,那么求解x02≡d(mod2q−k)x _ 0^2 \equiv d \pmod{2^{q-k}}x02d(mod2qk),然后解就是x=2k2(x0+2q−kt)x=2^{\frac{k}{2}}(x _ 0+2^{q-k}t)x=22k(x0+2qkt)的形式。
然后我们知道,当q=1q=1q=1的时候,当a=1a=1a=1时有解x=1x=1x=1
q=2q=2q=2时,当a=1a=1a=1时有解x=1,x=3x=1,x=3x=1,x=3
q=3q=3q=3时,当a=1a=1a=1时有解x=1,x=3,x=5,x=7x=1,x=3,x=5,x=7x=1,x=3,x=5,x=7
我们将q=kq=kq=k意义下解的形式写成xk=±(yk+tk2k−1)x _ k= \pm (y _ k+t _ k 2^{k-1})xk=±(yk+tk2k1)。记ak=a&VeryThinSpace;mod&VeryThinSpace;2ka_k = a \bmod{2^k}ak=amod2k
继续推,现在我们已知了xk−1≡±(yk−1+tk−12k−2)(mod2k−1)x _ {k-1}\equiv\pm(y _ {k-1}+t _ {k-1}2^{k-2}) \pmod{2^{k-1}}xk1±(yk1+tk12k2)(mod2k1)
那么xk−12x _ {k-1}^2xk12在模2k2^k2k意义下可能是ak−1a _ {k-1}ak1ak−1+2k−1a _ {k-1}+2^{k-1}ak1+2k1。我们在现在符合条件的若干tk−1t _ {k-1}tk1值中选择出能使xk−12≡ak(mod2k)x _ {k-1}^2 \equiv a _ k \pmod{2^k}xk12ak(mod2k)的,然后:
(yk−1+tk−12k−2)2≡ak(mod2k)(y _ {k-1}+t _ {k-1}2^{k-2})^2 \equiv a _ k \pmod{2^k}(yk1+tk12k2)2ak(mod2k)
将左边的式子拆开,得到yk−12+tk−12k−1yk−1+tk−1222k−4y _ {k-1}^2 + t _ {k-1}2^{k-1}y _ {k-1}+t _ {k-1}^2 2^{2k-4}yk12+tk12k1yk1+tk1222k4,由于我们之前已经保证过了aaa是奇数,所以yyy一定是奇数,而我们知道tk−12k−1×2≡0(mod2k)t_{k-1}2^{k-1} \times 2 \equiv 0 \pmod{2^k}tk12k1×20(mod2k)所以第二项一定等于tk−12k−1t_{k-1}2^{k-1}tk12k1。第三项则一定等于0。
所以
yk−12+tk−12k−1≡ak(mod2k)y _ {k-1}^2 + t _ {k-1}2^{k-1} \equiv a _ k \pmod{2^k}yk12+tk12k1ak(mod2k)
tk−12k−1≡ak−yk−12(mod2k)t _ {k-1}2^{k-1} \equiv a _ k -y _ {k-1}^2 \pmod{2^k}tk12k1akyk12(mod2k)
tk−1≡ak−yk−122k−1(mod2)t _ {k-1} \equiv \frac{a _ {k} - y _ {k-1}^2}{2^{k-1}} \pmod{2}tk12k1akyk12(mod2)
所以设tk−1=ak−yk−122k−1+2tkt _ {k-1}= \frac{a _ {k} - y _ {k-1}^2}{2^{k-1}} + 2 t _ ktk1=2k1akyk12+2tk,那么
xk=±(yk−1+ak−yk−122+2k−1tk)x _ k = \pm (y _ {k-1}+\frac{a _ k- y _ {k-1}^2}{2} + 2^{k-1}t _ k)xk=±(yk1+2akyk12+2k1tk)
也就是说,yk=yk−1+ak−yk−122y _ k=y _ {k-1}+\frac{a _ k- y _ {k-1}^2}{2}yk=yk1+2akyk12
所以我们就从q=3q=3q=3开始不断往上推,就可以出解了。

p为合数

嗯,将p质因数分解,然后分别求解,中国剩余定理合并即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值