Warning: session_start(): open(/tmp/sess_9ec8293e3940f1fadb6e33f0167b3b2e, O_RDWR) failed: No space left on device (28) in /data/wiki/inc/init.php on line 239
Warning: session_start(): Failed to read session data: files (path: ) in /data/wiki/inc/init.php on line 239
Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/auth.php on line 430
Writing /data/wiki/data/cache/d/de2edb2fcb553ea79b79c722a4e13dbc.captchaip failed
Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/Action/Export.php on line 103
Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/Action/Export.php on line 103
Warning: Cannot modify header information - headers already sent by (output started at /data/wiki/inc/init.php:239) in /data/wiki/inc/Action/Export.php on line 103
====== 二次剩余模板 ======
给定 $n$ 和 $p$ 求解关于 $x$ 的方程 $x^2\equiv n\pmod{p}$
===== 例题 =====
[[https://www.luogu.com.cn/problem/P5491|P5491 【模板】二次剩余]]
#include
using namespace std;
typedef long long ll;
int t;
ll n,p;
ll w;
struct num{
ll x,y;
};
num mul(num a,num b,ll p){
num ans={0,0};
ans.x=((a.x*b.x%p+a.y*b.y%p*w%p)%p+p)%p;
ans.y=((a.x*b.y%p+a.y*b.x%p)%p+p)%p;
return ans;
}
ll binpow_real(ll a,ll b,ll p){//实部快速幂
ll ans=1;
while(b){
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
ll binpow_imag(num a,ll b,ll p){//虚部快速幂
num ans={1,0};
while(b){
if(b&1) ans=mul(ans,a,p);
a=mul(a,a,p);
b>>=1;
}
return ans.x%p;
}
ll cipolla(ll n,ll p){
n%=p;
if(p==2) return n;
if(binpow_real(n,(p-1)/2,p)==p-1) return -1;
ll a;
while(1){
a=rand()%p;
w=((a*a%p-n)%p+p)%p;
if(binpow_real(w,(p-1)/2,p)==p-1) break;
}
num x={a,1};
return binpow_imag(x,(p+1)/2,p);
}
int main(){
srand(time(0));
scanf("%d",&t);
while(t--){
scanf("%lld %lld",&n,&p);
if(!n){
printf("0\n");continue;
}
ll ans1=cipolla(n,p),ans2;
if(ans1==-1) printf("Hola!\n");
else{
ans2=p-ans1;
if(ans1>ans2) swap(ans1,ans2);
if(ans1==ans2) printf("%lld\n",ans1);
else printf("%lld %lld\n",ans1,ans2);
}
}
return 0;
}