URAL 1132 二次剩余

1132. Square Root

Time limit: 1.0 second
Memory limit: 64 MB

The number x is called a square root of a modulo n (root(a,n)) if x*x = a (mod n). Write the program to find the square
root of number a by given modulo n.

Input

One number K in the first line is an amount of tests (K ≤ 100000). Each next line represents separate test, which contains integers a and n (1 ≤ an ≤
32767, n is prime, a and n are relatively prime).

Output

For each input test the program must evaluate all possible values root(a,n) in the range from 1 to n− 1 and output them in increasing order in one separate line using spaces.
If there is no square root for current test, the program must print in separate line: ‘No root’.

Sample

input output
5
4 17
3 7
2 7
14 31
10007 20011
2 15
No root
3 4
13 18
5382 14629

求x*x=a(mod n) 解x。利用勒让德符号。

题意:x^2=a(mod n)(gcd(a,n)=1,n为素数)(有解x升序输出,无解输出"No root"(不包含双引号))。

数论中,二次剩余的欧拉判别法(又称欧拉准则)是用来判定给定的整数是否是一个质数二次剩余

是奇质数不能整除,则:

是模的二次剩余当且仅当
是模的非二次剩余当且仅当:

勒让德符号表示,即为: 

费马小定理数论中的一个定理:假如a是一个整数p是一个质数,那么是p的倍数,可以表示为

如果a不是p的倍数,这个定理也可以写成

当n不整除a,n为奇素数时,方程x^2=a(mod n)有解<==>a^((n-1)/2)=1(mod n),此时a称之为n的二次剩余类。相反无解<==>a^((n-1)/2)=-1(或者用n-1表示)(mod n)(欧拉准则),此时称a为n的非二次剩余类。
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;

long long pow_mod(long long a,long long b,long long p)
{
    long long res=1;
    while(b>0)
    {
        if(b&1)res=(res*a)%p;
        a=(a*a)%p;
        b>>=1;
    }
    return res;
}

long long solve(long long a,long long p)
{
    long long q=p-1,s=0;
    while(q%2==0)
    {
        s++;
        q>>=1;
    }
    if(s==1)return pow_mod(a,(p+1)/4,p);
    long long z;
    while(1)
    {
        z = 1 + rand()%(p - 1);
        if(pow_mod(z, (p - 1)/2,p) != 1) break;
    }
    long long c = pow_mod(z, q , p);
    long long r = pow_mod(a, (q + 1)/2, p);
    long long t = pow_mod(a, q, p);
    long long m = s, b,i;
    while(1)
    {
        if(t%p==1)break;
        for(i=1; i<m; i++)if(pow_mod(t,1<<i,p)==1)break;
        b=pow_mod(c,1<<(m-i-1),p);
        r=(r*b)%p;
        c=(b*b)%p;
        t=(t*c)%p;
        m=i;
    }
    return r;
}

int main()
{
    long long a,p,i;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&a,&p);
        if(p==2)
        {
            if(a%p==1)printf("1\n");
            else printf("No root\n");
            continue;
        }
        if(pow_mod(a, (p-1)/2,p) != 1)
        {
            puts("No root");
            continue;
        }
        i=solve(a,p);
        if(p-i==i)printf("%I64d\n",i);
        else printf("%I64d %I64d\n",min(i,p-i),max(i,p-i));
    }
    return 0;
}
时间: 2024-09-20 00:15:03

URAL 1132 二次剩余的相关文章

POJ 2606 / URAL 1502 Rabbit hunt:计算几何

1052. Rabbit Hunt http://poj.org/problem?id=2606 http://acm.timus.ru/problem.aspx?space=1&num=1052 Time limit: 1.0 second Memory limit: 64 MB A good hunter kills two rabbits with one shot. Of course, it can be easily done since for any two points we

Ural 1019 Line Painting

点击打开链接ural 1019 思路:离散化 分析: 1 这一题的区间的最大值为10^9而n最大为5000,很明显就是利用离散化 2 题目中说了区间[0,10^9]刚开始为白色,而给定重刷的区间的值是大于0小于10^9的,所以我们应该开始就要考虑到0和10^9. 3 然后我们应该注意这题是对线段染色,所以我们应该要注意在处理的时候应该要把这些区间看成点来处理,然后会有两种方法分别是暴力和线段树 代码 线段树 #include<cstdio> #include<cstring> #i

light oj 1132 Summing up Powers

点击打开light oj 1132 思路: 构造矩阵+矩阵快速幂 分析: 1 题目给定n和k要求(1K + 2K + 3K+ ... + NK) % 232 2 具体的思路见下图    3 对于求组合数,我们可以利用公式C(n , k+1) = C(n , k)*(n-k)/(k+1) ,那么我们可以先打表求出50之内的所有的组合数 代码: /************************************************ * By: chenguolin * * Date: 2

Ural

Let's consider K-based numbers, containing exactly N digits. We define a number to be valid if itsK-based notation doesn't contain two successive zeros. For example: 1010230 is a valid 7-digit number; 1000198 is not a valid number; 0001235 is not a 7

算法:ural 1018 Binary Apple Tree(树形dp | 经典)

题意 给一棵边有权值的二叉树,节点编号为1-n,1是根节点.求砍掉一些边,只保留q条边,这q条边 构成的子树 的根节点要求是1,问这颗子树的最大权值是多少? 思路 非常经典的一道树形dp题 ,根据我目前做过的题来看,有多道都是由这题衍生出来的. f(i, j) 表示子树i,保留j个节点(注意是 节点)的最大权值.每条边的权值,把它看作是连接的两个节点中的儿子节点的权值. 那么,就可以对所 有i的子树做分组背包,即每个子树可以选择1,2,...j-1条边分配给它. 状态转移为: f(i, j) =

URAL 1698 自守数

好吧 苟哥总结好了我直接粘了 自守数的定义   对于一个k位的自然数n,如果它的平方后的最后k位跟原数相同,那么n就叫做自守数.数学定义表达式为:.   一位数的自守数有三个,分别为1,5,6.两位数以上的自守数分为A.B两类,A类是以5结尾,B类是以6结尾. 例如,以5结尾的自守数有25,625,90625等:以6结尾的自守数有76.376.9376等. 两类自守数的一个基本性质是:相同位数的两类自守数的和相加等于自守数的位数乘10再加上1,即:   5+6=10+1 25+76=100+1

URAL 1133 二分

给出广义斐波那契数列的任意两项,让求这个斐波那契数列的其他项. 这题解方程的话精度不够所以二分求出f[a+1]这一项的值.二分的时候如果超范围直接跳出.再通过f[a]与f[a+1]求出任意一项.写得好挫啊. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int judge(long long x,long long

URAL 1043 三角形外接圆

题意:给出一个圆弧上的三个点,求出一个边平行于坐标轴面积最小的矩形并且这个矩形可以给这个圆弧覆盖掉,求矩形面积. 步骤: 1.先求出给出三点围城三角形的外接圆,圆弧就是这个圆的一部分. 2.找出外接圆的上下左右四个端点. 3.枚举四个端点如果在弦ab 跟c同侧那么圆弧肯定过这一点,记下这点的极值.用叉积判断同号即可. 4.特判端点大于1000的情况然后输出面积即可. 这题精度好难调.求外接圆圆心一步求出.分成变量存可能有精度问题,eps必须要有,不然会出错.WA10 5 6次. #include

URAL 1456 求a模n的阶

首要条件是a,n互素,也就是求a^x=1(n)最小的x,根据欧拉函数可知最大为n的欧拉函数值.所以n的欧拉函数值的因子就可以了. #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<set> using namespace std; #define