二次剩余

2019-04-13 14:44发布

class="markdown_views prism-atelier-sulphurpool-light">

引言

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

p为奇素数

首先引入欧拉准则
aa为模pp意义下的二次剩余时,ap121(modp)a^{frac{p-1}{2}} equiv 1 pmod{p}
aa为模pp意义下的非二次剩余时,ap12p1(modp)a^{frac{p-1}{2}} equiv p-1 pmod{p}
我们要求的xx满足:(a1x2)201(modp)(a^{-1}x^2)^{2^0} equiv 1 pmod{p}
p1=s2tp-1=s2^t,设xt1=as+12x _ {t-1}=a^{frac{s+1}{2}},那么根据欧拉准则第一条,有:(a1xt12)2t11(modp)(a^{-1}x_{t-1}^2)^{2^{t-1}} equiv 1 pmod{p}
诶…要不我们设(a1xtk2)2tk1(modp)(a^{-1}x _ {t-k}^2)^{2^{t-k}} equiv 1 pmod{p},这样我们要求的就是x0x_0
思考如何从xtkx _ {t-k}推到xtk1x _ {t-k-1}
etk=a1xtk2e _ {t-k}=a^{-1}x _ {t-k}^2
etk2tk11(modp)e _ {t-k}^{2^{t-k-1}} equiv 1 pmod{p}(即将etk2tke _ {t-k}^{2^{t-k}}开根),显然xtk1=xtkx _ {t-k-1}=x _ {t-k}
etk2tk1p1(modp)e _ {t-k}^{2^{t-k-1}} equiv p-1 pmod{p}。我们试图让xtkx _ {t-k}乘一个值使得它变成xtk1x _ {t-k-1}。那么想到欧拉准则的第二条,首先随机一个非二次剩余bb,然后发现(b2k1s)2tkp1(modp)(b^{2^{k-1}s})^{2^{t-k}} equiv p-1 pmod{p},所以b2k1sb^{2^{k-1}s}是我们满足条件的值,此时让xtk1=b2k1sxtkx _ {t-k-1}=b^{2^{k-1}s}x _ {t-k}即可。
最后x0x_0其实有正负两个解,都满足条件。
例题:URAL 1132
代码: #include 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; }

热门文章