[求解二次剩余 数论技巧 随机化] Ural 1132 Square Root

来源:互联网 发布:淘宝知识产权申诉成功 编辑:程序博客网 时间:2024/04/26 21:01

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1132


以下来自:http://blog.csdn.net/acdreamers/article/details/10182281


今天要讨论的问题是解方程,其中是奇质数。

 

引理:

 

证明:由费马小定理,

 

引理:方程有解当且仅当

 

定理:满足不是模的二次剩余,即无解,那么是二次

     剩余方程的解。

 

证明:,前面的等号用二项式定理和,后面的等

     号用了费马小定理和是模的二次非剩余。然后

 

      

 

在算法实现的时候,对的选择可以随机,因为大约有一半数是模的二次非剩余,然后快速幂即可。



#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }  return *p1++;}inline void read(ll &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}ll P;inline ll Pow(ll a,ll b){  ll ret=1;  for (;b;b>>=1,a=a*a%P)    if (b&1)      ret=ret*a%P;  return ret;}inline ll legendre(ll a){  return Pow(a,(P-1)>>1);}struct abcd{  ll a,b,w; //a+b*sqrt(w)  abcd(ll a=0,ll b=0,ll w=0):a(a),b(b),w(w) { }  friend abcd operator *(abcd A,abcd B){    return abcd((A.a*B.a%P+A.b*B.b%P*A.w%P)%P,(A.a*B.b%P+A.b*B.a%P)%P,A.w);  }};inline abcd Pow(abcd a,int b){  abcd ret=abcd(1,0,a.w);  for (;b;b>>=1,a=a*a)    if (b&1)      ret=ret*a;  return ret;}inline ll Solve(ll n,ll p){  P=p;  if (P==2) return 1;  if (legendre(n)==P-1) return -1;  ll a,w;  while (1){    a=rand()%P;    w=((a*a-n)%P+P)%P;    if (legendre(w)==P-1) break;  }  return Pow(abcd(a,1,w),(P+1)>>1).a;}int main(){  srand(10086);  ll n,p,T,ans,a,b;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(T);  while (T--){    read(n); read(p);    ans=Solve(n,p);    if (ans==-1)      printf("No root\n");    else if (ans==p-ans)printf("%lld\n",ans);    else if (ans<P-ans)      printf("%lld %lld\n",ans,P-ans);    else      printf("%lld %lld\n",P-ans,ans);  }  return 0;}


以下来自:http://blog.csdn.net/acdreamers/article/details/10182281


接下来我们来解另一个二次同余方程的解,其中,并且是奇质数。方法如下

 

先求出方程的一个解,那么进一步有

 

      

 

我们知道

 

      

 

那么也就是说

 

       

 

可以证明,那么最终得到

 

       

 

这里由于不是素数,所以求逆元用扩展欧几里得算法即可。

 



0 0