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\n",ans1,ans2);
    }
    return 0;
}

URAL1132_Square Root

时间: 2024-08-29 23:56:12

URAL1132_Square Root的相关文章

LeetCode OJ - Sum Root to Leaf Numbers

这道题也很简单,只要把二叉树按照宽度优先的策略遍历一遍,就可以解决问题,采用递归方法越是简单. 下面是AC代码: 1 /** 2 * Sum Root to Leaf Numbers 3 * 采用递归的方法,宽度遍历 4 */ 5 int result=0; 6 public int sumNumbers(TreeNode root){ 7 8 bFSearch(root,0); 9 return result; 10 } 11 private void bFSearch(TreeNode ro

《linux破解root密码》

以下实验操作基于RHEL7.0下进行 步骤如下: 1. 重启系统 2. 按任意键,以中断启动加载器的倒计时. 3. 把光标移动到需要启动的条目. 4. 按e键,编辑该条目 把光标移动到linux16开头的行. 删除 console=ttys0,115200n8 在该行末尾,输入一个空格,然后添加  rd.break 注:rd.break表示控制权从initramfs转移到实际系统之前,进行中断. 5.  ctrl+x使用该改动并启动 启动好后,实际的根文件系统,以只读方式挂载到 /sysroot

MySQL更改默认的root账户密码

编辑mysql的配置文件:my.ini(在MySql安装目录下). 打开配置文件,在文件最后一行添加:skip-grant-tables,然后保存退出 意思为就是在启mysql时不启动grant-tables 重启MySql服务:(在命令行窗口中,需要事先把MySQL的bin路径添加到环境变量当中,或者通过在服务中重新启动) net stop mysql net start mysql 设置新的root密码 mysql -u root -p 直接回车,无需输入密码就可以进入数据库了.(或者直接敲

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

linux下添加用户并赋予root权限

1.添加用户,首先用adduser命令添加一个普通/系统用户,命令如下:# adduser [-r] –d /tommy tommy//添加一个名为tommy的用户 # passwd tommy   //修改密码Changing password for user tommy.New UNIX password:     //在这里输入新密码Retype new UNIX password:  //再次输入新密码passwd: all authentication tokens updated

Nignx入门location、root配置

nginx的配置.首当其冲的就是location配置了,下面是笔记参考的博文链接点这里 location匹配的是nginx的哪个变量? $request_uri (这个不懂怎么用) location的匹配种类有哪些? 格式 location [ 空格 | = | ~ | ~* | !~ | !~* ] /uri/ {} # 精确匹配: 相等(=) # 字符串匹配: 字符串匹配(空格) 匹配开头(^~) # 正则匹配: 区分大小写匹配(~) 不区分大小写匹配(~*) 区分大小写不匹配(!~) 不区

CentOS禁用本地root和远程ssh登录

某天为解决su切换慢的问题,黄哥修改了一个加载脚本,导致普通用户无法切换root用户,su输入密码后登录还是普通用户.当初设置禁止root登录时,未给某个特定用户增加sudo权限,导致现在所有程序无法使用(telnet服务同样被禁止了).最后通过将该系统盘挂载到另外一台服务器上,将脚本改回为原来状态解决问题. 正常后登录服务器检查CentOS使用版本为6.4,因数据安全要禁用root本地和远程ssh登录,只给普通用户权限. 禁止root本地登录 修改配置/etc/pam.d/login,增加如下

使用单用户模式修改root密码

Linux系统的单用户模式类似于Windows系统的安全模式,允许用户进行一些操作,比如启动一些关键服务.在没有设置grub密码的前提下,我们可以使用单用户模式更改或重置root密码. 1.打开虚拟机 2.开机3秒内按任意键进入编辑菜单 3.编辑菜单中方向键"上"."下"用来选择条目,按"e"编辑命令:按"a"修改内核参数:按"c"进入命令行.这里我们按"e"进入编辑模式. 4.方向键&

MySQL忘记root密码后修改

MySQL忘记root密码后可以使用下面的方法修改. 1.登录MySQL所在的服务器,手工kill掉MySQL进程 kill `cat $mysql_data_dir/hostname.pid` $mysql_data_dir/hostname.pid为MySQL数据目录,它记录了MySQL服务的进程号. [[email protected] ~]# ps -ef |grep mysql root      6602     1  0 21:39 ?        00:00:00 /bin/s