zoukankan      html  css  js  c++  java
  • 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; }
    
    
    

  • 相关阅读:
    概率论中几个入门公式
    记一道贝叶斯公式的裸题
    BZOJ3585: mex(主席树)
    利用MingW检验程序运行内存
    清北集训Day3T1(转换)
    万能pb_ds头文件—bits/extc++.h
    清北集训Day1T3 LYK loves jumping(期望DP)
    洛谷P1962 斐波那契数列(矩阵快速幂)
    namespace用法
    BZOJ4868: [Shoi2017]期末考试
  • 原文地址:https://www.cnblogs.com/xiong-/p/3238149.html
Copyright © 2011-2022 走看看