https://zhuanlan.zhihu.com/p/166123245
关于
(
a
+
w
)
p
+
1
2
(a+\sqrt w)^{\frac{p+1}{2}}
(a+w)2p+1 的虚部为
0
0
0 证明
TLY巨佬%%%
可以得到
(
a
+
w
)
p
≡
a
p
+
w
p
−
1
2
w
≡
a
−
w
(
m
o
d
p
)
(a+\sqrt w)^p\equiv a^p+w^{\frac{p-1}{2}}\sqrt w\equiv a-\sqrt w(mod\ p)
(a+w)p≡ap+w2p−1w≡a−w(mod p)
(
a
+
w
)
p
+
1
≡
n
(
m
o
d
p
)
(a+\sqrt w)^{p+1}\equiv n(mod\ p)
(a+w)p+1≡n(mod p)
反证法
设
(
a
+
w
)
p
+
1
2
=
x
+
y
w
(a+\sqrt w)^{\frac{p+1}{2}}=x+y\sqrt w
(a+w)2p+1=x+yw
(
a
+
w
)
p
+
1
≡
(
x
+
y
w
)
2
=
x
2
+
y
2
w
+
2
x
y
w
≡
n
(
m
o
d
p
)
(a+\sqrt w)^{p+1}\equiv (x+y\sqrt w)^2=x^2+y^2w+2xy\sqrt w\equiv n(mod\ p)
(a+w)p+1≡(x+yw)2=x2+y2w+2xyw≡n(mod p)
那么
x
y
=
0
xy=0
xy=0
假设
x
=
0
,
y
≠
0
x=0,y\not=0
x=0,y=0
则
y
2
w
=
n
y^2w=n
y2w=n 其中左边不是二次剩余,右边是,矛盾(用逆元证明更好)
所以
x
≠
0
,
y
=
0
x\not=0,y=0
x=0,y=0
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<deque>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<tr1/unordered_map>
using namespace std;
#define LL long long
LL read(){
LL f=1,x=0;char c=getchar();
while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}
while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return f*x;
}
#define INF 0x3f3f3f3f
#define MAXN 2000000
LL w,Mod;
struct Comp{
LL x,y;
friend Comp operator * (Comp a,Comp b){
return (Comp){(a.x*b.x%Mod+a.y*b.y%Mod*w%Mod)%Mod,(a.x*b.y%Mod+a.y*b.x%Mod)%Mod};
}
};
LL Pow(LL x,LL y){
LL ret=1;
while(y){
if(y&1) ret=ret*x%Mod;
x=x*x%Mod,y>>=1;
}
return ret;
}
Comp Pow(Comp x,LL y){
Comp ret=(Comp){1,0};
while(y){
if(y&1) ret=ret*x;
x=x*x,y>>=1;
}
return ret;
}
//勒让德符号
LL Legendre(LL n){
return Pow(n,(Mod-1)>>1);
}
LL Quadratic_Residue(LL n){
if(Mod==2) return 1;
if(Legendre(n)==Mod-1)
return -1;
LL a;
while(1){
a=rand()%Mod;
w=(a*a%Mod+Mod-n)%Mod;
if(Legendre(w)==Mod-1)
break;
}
Comp ret=(Comp){a,1};
ret=Pow(ret,(Mod+1)>>1);
return ret.x;
}
int main(){
int Test=read();
while(Test--){
LL n=read();Mod=read();
n%=Mod;
LL x1=Quadratic_Residue(n);
if(x1==-1){
puts("No root");
continue;
}
LL x2=Mod-x1;
if(x1>x2) swap(x1,x2);
printf("%lld %lld\n",x1,x2);
}
return 0;
}