二次剩余
先记几个结论:
- 。
- 。
- 若 是 的二次剩余, 有两根,且两根互为相反数。
- 若 不是二次剩余,令 ,那么 的其中一根为 ,即 。
- 。
求解 :
变量
- :二次剩余。
- :模数。
- :。
函数
- : 位随机数。
- :虚数结构体。
- :整数快速幂。
- :虚数快速幂。
- :用 方法求解,模数为 ,若无解则返回 。
代码
ll ii,p;
ll get(ll n){
return (((rand()<<16ll)%n+n+(rand()))%n+1);
}
struct xushu{
ll a,b;
xushu operator+(const xushu x)const{
return (xushu){(a+x.a)%p,(b+x.b)%p};
}
xushu operator*(const xushu x)const{
return (xushu){(a*x.a%p+ii*b%p*x.b%p)%p,(b*x.a%p+a*x.b%p)%p};
}
}res;
ll qmi(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%p;
a=a*a%p;b>>=1;
}
return ans;
}
xushu qmi(xushu a,ll b){
xushu ans;ans.a=1;ans.b=0;
while(b){
if(b&1)ans=ans*a;
a=a*a;b>>=1;
}
return ans;
}
pair<ll,ll> Cipolla(ll n,ll pp){
srand(time(0));
ll a;p=pp;
if(!n)return make_pair(0,0);
if(qmi(n,(p-1)/2)!=1)return make_pair(-1,-1);
do{
a=get(p-1);
}while(qmi((a*a%p-n%p+p)%p,(p-1)/2)==1);
ii=(a*a%p-n%p+p)%p;
res.a=a;res.b=1;
res=qmi(res,(p+1)/2);
ll ans1=res.a,ans2=p-res.a;
if(ans1>ans2)swap(ans1,ans2);
return make_pair(ans1,ans2);
}

浙公网安备 33010602011771号