uva 1426 离散平方根

1426 - Discrete Square Roots

Time limit: 3.000 seconds

A square root of a number x <tex2html_verbatim_mark>is a number r <tex2html_verbatim_mark>such that r2 = x <tex2html_verbatim_mark>. A discrete square root of a non-negative integer x <tex2html_verbatim_mark>is a non-negative integer r <tex2html_verbatim_mark>such thatr2 $ equiv$ x mod N <tex2html_verbatim_mark>, 0$ le$r < N <tex2html_verbatim_mark>, where N <tex2html_verbatim_mark>is a specific positive integer and mod is the modulo operation.

It is well-known that any positive real number has exactly two square roots, but a non-negative integer may have more than two discrete square roots. For example, for N = 12 <tex2html_verbatim_mark>, 1 has four discrete square roots 1, 5, 7 and 11.

Your task is to find all discrete square roots of a given non-negative integer x <tex2html_verbatim_mark>. To make it easier, a known square root r <tex2html_verbatim_mark>of x <tex2html_verbatim_mark>is also given to you.

 

Input 

The input consists of multiple test cases. Each test case contains exactly one line, which gives three integers x <tex2html_verbatim_mark>, N <tex2html_verbatim_mark>and r <tex2html_verbatim_mark>. (1$ le$x < N, 2$ le$N < 1, 000, 000, 000, 1$ le$r < N) <tex2html_verbatim_mark>. It is guaranteed that r <tex2html_verbatim_mark>is a discrete square root of x<tex2html_verbatim_mark>modulo N <tex2html_verbatim_mark>. The last test case is followed by a line containing three zeros.

 

Output 

For each test case, print a line containing the test case number (beginning with 1) followed by a list of corresponding discrete square roots, in which all numbers are sorted increasingly..

 

Sample Input 

 

1 12 1 
4 15 2 
0 0 0

 

Sample Output 

 

Case 1: 1 5 7 11 
Case 2: 2 7 8 13

题意:r^2≡x(mod n)求(0<r<n)r的所有解
已知x,n,跟一个解r1,那么有
r^2≡x (mod n)即:r^2+k1*n=x;(1)
r1^2≡x (mod n)即:r1^2+k2*n=x;(2)
联立(1)、(2)得:r^2-r1^2=(r+r1)(r-r1)=k3*n;(3)
枚举A和B使得:A * B =n
r + r1≡0 (mod A)
r - r1≡0 (mod B)
即: Ak-r1= Bk + r1= r
变形一下得:Ak≡2*r1 (mod B)
根据这个等式枚举模线性方程求解
根据一般的模线性方程求解我的每组案例都少了个解,改成枚举n(A*B=Kn)范围内所有的解而不是B范围内(Ak≡2*r1(mod B))
我觉得用int型应该差不多了,可是Wrong answer,改成long long,却Accepted了。
AC代码:
#include<iostream>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<set>
using namespace std;

typedef long long LL;
set<LL> s;
LL X,R,N;

LL Extended_Euclid(LL a,LL b,LL &x,LL &y)//欧几里德扩展定理
{ LL d,t;
if(b==0) { x=1;y=0;return a; } d=Extended_Euclid(b,a%b,x,y); t=x; x=y; y=t-a/b*y; return d; } void Mod_Line_Equation_Solve(LL a,LL b,LL n)//模线性方程求解
{ LL x,y,d,t,lcm; d
=Extended_Euclid(a,n,x,y); if(b%d==0) { x=x*b/d; x=(x%(n/d)+n/d)%(n/d); t=a*x-b/2; lcm=a/d*n; for(;t<N;t+=lcm) { if(t>=0 && t*t%N==X) s.insert(t);//符合条件的解插入set容器
} } }
int main() { LL i,top,Case=0; while(cin>>X>>N>>R && !(X==0 && N==0 && R==0)) { Case++; printf("Case %d:",Case); s.clear(); top=sqrt(N+0.5); for(i=1;i<=top;i++)//枚举所有的A*B=n的情况
{
if(N%i==0) { Mod_Line_Equation_Solve(i,2*R,N/i); Mod_Line_Equation_Solve(N/i,2*R,i); } } set<LL>::iterator it; for(it=s.begin();it!=s.end();it++) printf(" %lld",*it); printf(" "); } return 0; }



原文地址:https://www.cnblogs.com/xiong-/p/3238149.html