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 x mod N <tex2html_verbatim_mark>, 0
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>. (1x < N, 2
N < 1, 000, 000, 000, 1
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("\n"); } return 0; }