zoukankan      html  css  js  c++  java
  • URAL1132_Square Root

    求解方程,x^2=n (mod P)。

    解二次同余方程的步骤:

    1、首先判断勒让德符号(n,p)是否的等于1,即n^((p-1/2)=1 (mod p)是否成立。不成立显然无解。(略)

    2、任取0-(p-1)中的一a值,判断w=a*a-n是否是P的二次同余,直到找到一个否定的答案即可。(大约有一半是否定答案)

    3、根据找到的w,(a+sqrt(w))^((p+1)/2)就是二次同余的解,同时最多只有两解,且两数之和为P。(要用到二次域,囧rz)

    中间有一定量的推导过程,但是不是很难,琢磨琢磨吧。

    对于这个题目,注意一种特殊情况,p=2时,直接输出1即可。

    召唤代码君:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    
    int a,w;
    int T,n,p,A0,B0;
    
    struct twice{
        int A,B;
        twice() { }
        twice(int AA,int BB) { A=AA,B=BB; }
        twice operator * ( twice T ) const {
            A0=A*T.A+(B*T.B)%p*w;
            B0=A*T.B+B*T.A;
            return twice(A0%p,B0%p);
        }
    };
    
    int power(int A,int B)
    {
        int C=1;
        while (B){
            if (B&1) C=C*A%p;
            A=A*A%p,B>>=1;
        }
        return C;
    }
    
    twice power(twice A,int B)
    {
        twice C(1,0);
        while (B){
            if (B&1) C=C*A;
            A=A*A,B>>=1;
        }
        return C;
    }
    
    bool lgd(int A,int B)
    {
        return power(A,(B-1)/2)==1;
    }
    
    int main()
    {
        scanf("%d",&T);
        while (T--){
            scanf("%d%d",&n,&p);
            if (p==2){
                puts("1");
                continue;
            }
            if (!lgd(n,p)){
                puts("No root");
                continue;
            }
            for (;;){
                a=rand()%p;
                w=((a*a-n)%p+p)%p;
                if (!lgd(w,p)) break;
            }
            twice T(a,1);
            T=power(T,(p+1)/2);
            int ans1=(int)T.A,ans2=(int)p-T.A;
            if (ans1>ans2) swap(ans1,ans2);
            printf("%d %d
    ",ans1,ans2);
        }
        return 0;
    }
  • 相关阅读:
    HDU 1202 The calculation of GPA
    HDU 1201 18岁生日
    HDU 1200 To and Pro
    C语言实现的图的深度搜索与广度搜索程序
    深度优先搜索和广度优先搜索的深入讨论
    Linux sftp 安全文件传输命令
    看白鹿原有感
    中国人民抗日战争暨世界反法西斯战争胜利70周年(20150903)
    高一的我曾对自己说"要放慢脚步去生活"!?
    网络营销(续)
  • 原文地址:https://www.cnblogs.com/lochan/p/3886868.html
Copyright © 2011-2022 走看看