传送门
写在前面:ACdreamer大神太强辣!希望能达到他一半的高度啊!
思路:ACdreamer’s blog
裸题调了好久ORZ
注意:关于(a+√w)^((p+1)/2)的求法,我至今都没太想明白……
代码:
#include"bits/stdc++.h"
using namespace std;
int t,a,x,p,w;
struct os
{
int u,v;
};
os mul(os a,os b)
{
os c;
c.u=(a.u*b.u%p+a.v*b.v%p*w%p)%p;
c.v=(a.u*b.v%p+a.v*b.u%p)%p;
return c;
}
int qr(int x,int y,int z)
{
int ans=1;
while (y)
{
if (y&1) ans=ans*x%p;
y>>=1;
x=x*x%z;
}
return ans;
}
main()
{
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&x,&p);
if (p==2) {printf("1\n");continue;}
if (qr(x,(p-1)>>1,p)-p==-1)
{
printf("No root\n");
continue;
}
while (1)
{
a=rand()%p;
w=a*a-x;
w%=p;
while (w<0) w+=p;
if (qr(w,(p-1)>>1,p)-p==-1) break;
}
int yy=(p+1)>>1;
os ans,xx;
ans.u=1;
ans.v=0;
xx.u=a;
xx.v=1;
while(yy)
{
if (yy&1) ans=mul(ans,xx);
xx=mul(xx,xx);
yy>>=1;
}
int ans1=ans.u,ans2=p-ans.u;
if (ans1==ans2) printf("%d\n",ans1);
else printf("%d %d\n",min(ans1,ans2),max(ans1,ans2));
}
}