ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二次剩余(懒人模板总结)

2020-06-04 15:05:39  阅读:240  来源: 互联网

标签:剩余 frac 原根 int 懒人 pmod sqrt 模板


二次剩余(懒人模板总结)

只考虑奇质数的情况

设求\(\sqrt a \pmod P\)

Part1 判断

存在二次剩余即\(a^{\frac{(P-1)}{2}}=1 \pmod P\)


(对于所有\(a=0,1\)的情况需要特判)

Part2 原根法求二次剩余

先求出\(P\)的一个原根\(g\)

那么可以用\(g^k\)表示出\([1,P-1]\)的所有数

用\(BSGS\)可以在\(O(\sqrt n\log n)\)的时间内求出\(a=g^k\)

如果存在原根,那么\(k\mod 2=0\)

答案就是\(g^{\frac{k}{2}}\mod P\)

int Quad(int a,int k=0) {
	if(a<=1) return a;    
    int g=Getg(P);
	static map <int,int> M;
	int S=sqrt(P-1);
	for(int i=0,t=1;i<S;++i,t=1ll*t*g%P) M[t]=i;
	int res=0;
	int w=qpow(g,S);
	for(int i=0,t=1;i<P-1;i+=S,t=1ll*t*w%P) {
		ll x=1ll*a*qpow(t,P-2)%P;
		if(M.count(x)) {
			res=M[x]+i;
			break;
		}
	}
	res=qpow(g,res/2);
	if(k) res=min(res,(P-res)%P);
	return res;
}

Part3 更快的方法

要先找到一个数\(x\),满足不存在\(\sqrt{x^2-a}\pmod P\)

可以随机\(x\),期望可以在\(O(1)\)时间内找到这样的\(x\)

然后构造复数\((\alpha,\beta)=\alpha+\sqrt{x^2-a}\beta\)

求出\((x,1)^{\frac{(P+1)}{2}}\),模拟复数乘法即可

可以证明结果没有虚部,就是答案

int Quad(int a,int k=0) {
	if(a<=1) return a;
	int x;
	while(1) {
		x=1ll*rand()*rand()%P;
		ll res=qpow((1ll*x*x-a+P)%P,(P-1)/2);
		if(res!=1) break;
	}
	ll w=(1ll*x*x-a+P)%P;
	int d=(P+1)/2;
	ll resx=1,resy=0;
	ll xx=x,yy=1;
	while(d) {
		if(d&1) {
			ll tx=(resx*xx+resy*yy%P*w)%P,ty=(resx*yy+resy*xx)%P;
			resx=tx,resy=ty;
            // 模拟复数乘法
		}
		ll tx=(xx*xx+yy*yy%P*w)%P,ty=2*xx*yy%P;
		xx=tx,yy=ty;
        // 模拟复数乘法
		d>>=1;
	}
	x=resx; // 答案就是实部
	if(k) x=min(x,(P-x)%P);
	return x;
}


标签:剩余,frac,原根,int,懒人,pmod,sqrt,模板
来源: https://www.cnblogs.com/chasedeath/p/13043597.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有