您的位置:首页 > 其它

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

2016-11-06 20:33 483 查看
题目链接: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

接下来我们来解另一个二次同余方程

的解,其中

,并且

是奇质数。方法如下

 

先求出方程

的一个解

,那么进一步有

 

      


 

我们知道

 

      


 

那么也就是说

 

       


 

可以证明



,那么最终得到

 

       


 

这里由于

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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: