TJOI 2017 (Pollard_rho,MR素数测试)

MR素性探测 MR素性探测 简介 MR算法全称是Miller-Rabin测试,是一个非确定的算法,用于判断一个数是否是质数.虽然是一个非确定的算法,但是只要巧妙地选取参数,在一定范围内就是一个确定性的算法. 前置条件:费马小定理 1 ≡ a^(p-1) (mod p) Miller和Rabin两个人的工作让Fermat素性测试迈出了革命性的一步,建立了传说中的Miller-Rabin素性测试算法。 新的测试基... 阅读详情

TJOI 2017 (Pollard_rho,MR素数测试)

题目链接

题意是求分数 B A \frac{B}{A} AB​在模M下的逆元,没有则输出-1。

本题的两大核心是:Pollard_rho算法,和MR素数测试算法。

B A \frac{B}{A} AB​在模M下有逆元当且仅当 g c d ( A , M ) = 1 gcd(A,M)=1 gcd(A,M)=1,因为分数不是最简的,所以只要分数可以化简到 B ′ A ′ \frac{B'}{A'} A′B′​,其中 g c d ( A ′ , M ) = 1 gcd(A',M)=1 gcd(A′,M)=1即有逆元。

我一开始的思路是先将 B A \frac{B}{A} AB​化到最简分数 B ′ A ′ \frac{B'}{A'} A′B′​,再判断A’是否有逆元。由于B’和A‘超出了264的范围,所以不能直接求 g c d gcd gcd以及约分。因为 A = a 1 ⋅ a 2 ⋯ a m , B = b 1 ⋅ b 2 ⋯ b m A=a_1\cdot a_2\cdots a_m,B=b_1\cdot b_2\cdots b_m A=a1​⋅a2​⋯am​,B=b1​⋅b2​⋯bm​,所以可以通过依次求ai,bi的质因子分解式,将A,B的质因子分解式求出,在通过A,B的质因子分解式去化简 B A \frac{B}{A} AB​,再求M的质因子分解式,这样就可以判断是否 g c d ( A ′ , M ) = 1 gcd(A',M)=1 gcd(A′,M)=1了。

思路是简单明了的,答案能也保证正确,但是TLE。

在参考了别人的代码后,我发现并不用求A,B的质因子分解式,甚至也不用求M的质因子分解式,只需要求M的质因子集合即可。其实并不需要将 B A \frac{B}{A} AB​化到最简,只需要将 B A \frac{B}{A} AB​化简到 B ′ A ′ \frac{B'}{A'} A′B′​使得 g c d ( A ′ , M ) = 1 gcd(A',M)=1 gcd(A′,M)=1即可。

在得到M的质因子集合 s = { p 1 , p 2 , ⋯ p n } s=\{p_1,p_2,\cdots p_n\} s={p1​,p2​,⋯pn​}之后,想要让 g c d ( A ′ , M ) = 1 gcd(A',M)=1 gcd(A′,M)=1,那么A’必须不能包含集合s里面的质因子。因为 A = a 1 ⋅ a 2 ⋯ a m A=a_1\cdot a_2\cdots a_m A=a1​⋅a2​⋯am​,所以我们依次检查ai是否能被pj整除,若能整除,则一定有 a i = a i ′ ∗ p j e j a_i=a^{'}_i*p_j^{e_j} ai​=ai′​∗pjej​​,保留 a ′ a^{'} a′并统计 e j e^j ej。得到的 A ′ = a 1 ′ ⋅ a 2 ′ ⋯ a n ′ A'=a^{'}_1\cdot a^{'}_2\cdots a^{'}_n A′=a1′​⋅a2′​⋯an′​满足于M互质。
因为我们需要保证变化后的分数是等价的,所以每当A除以一个pj时,我们还需判断B是否也能除以一个pj。若不能,则说明 B A \frac{B}{A} AB​化简后的 B ′ A ′ \frac{B'}{A'} A′B′​中的A’中必含有集合s里面至少一个素因子。所以我们还需统计 B = b 1 ⋅ b 2 ⋯ b m , b i = b i ′ ∗ p j e j B=b_1\cdot b_2\cdots b_m,b_i=b^{'}_i*p_j^{e_j} B=b1​⋅b2​⋯bm​,bi​=bi′​∗pjej​​中的ej。

可以用一个数组e,初始化e[i]=0:
对于 a i = a i ′ ∗ p j e j a_i=a^{'}_i*p_j^{e_j} ai​=ai′​∗pjej​​,e[j]-=ej。
对于 b i = b i ′ ∗ p j e j b_i=b^{'}_i*p_j^{e_j} bi​=bi′​∗pjej​​,e[j]+=ej。

若存在e[j]<0,则说明 B A \frac{B}{A} AB​并不存在逆元。
若对于所有e[j]>=0,则一定存在逆元。

注意,最后得到的 A ′ = a 1 ′ ⋅ a 2 ′ ⋯ a n ′ A'=a^{'}_1\cdot a^{'}_2\cdots a^{'}_n A′=a1′​⋅a2′​⋯an′​, B ′ = b 1 ′ ⋅ b 2 ′ ⋯ b n ′ B'=b^{'}_1\cdot b^{'}_2\cdots b^{'}_n B′=b1′​⋅b2′​⋯bn′​组成的 B ′ A ′ \frac{B'}{A'} A′B′​并不等价于原来的分数,因为可能存在e[i]>0,说明了B在约去了A中包含的质因子pi之外还多约了 p i e [ i ] p_i^{{e[i]}} pie[i]​。所以需将多约去的返还给B。

(不明白题目保证1<M,ai,bi<2*10^8,但是64bits的long long 过不了?)
所以本题实现使用了__int128。

代码如下:

#include<iostream>
#include<cstdio>
#include<utility>
#include<unordered_map>
#include<vector>
#include<algorithm>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
const int max_n=1e4+5; 
ll b[max_n];
ll a[25][max_n];
ll c[55];
ll M[55];
ll aa[max_n],bb[max_n];
ll n,m,k;
vector<ll> f;
ll gcd(ll a,ll b)
{
	ll t;
	while(b)
	{
		t=a;
		a=b;
		b=t%b;
	}
	return a;
}
ll qpow(ll a,ll n,ll mod)
{
	ll ans=1;
	while(n)
	{
		if(n&1)ans=(__int128)ans*a%mod;
		a=(__int128)a*a%mod;
		n>>=1;
	}
	return ans;
}
bool mr_test(ll n)
{
	if(n<2)return false;
	else if(n==2)return true;
	else if(n%2==0)return false;
	ll a=n-1,b=0;
	while(a%2==0)a/=2,b++;
	for(int i=0;i<10;i++)
	{
		ll x=rand()%(n-2)+2;
		ll y=qpow(x,a,n);
		for(int j=0;j<b;j++)
		{
			x=(__int128)y*y%n;
			if(x==1&&y!=1&&y!=n-1)return false;
			y=x;
		}
		if(y!=1)return false;
	}
	return true;
}
void pollard_rho(ll n)
{
	if(n==1)return ;
	if(mr_test(n)){
		f.push_back(n);
		return ;
	}
	ll c=rand()%(n-1)+1;
	ll s=0,t=0;
	ll v=1;
	ll goal,step=1;
	for(goal=1;;goal<<=1,s=t,v=1)
	{
		for(;step<=goal;step++)
		{
			t=((__int128)t*t%n+c)%n;
			v=(__int128)v*abs(t-s)%n;
			if(step%127==0)
			{
				ll d=gcd(v,n);
				if(d>1){
					while(n%d==0)n/=d;
					pollard_rho(n);
					pollard_rho(d);
					return ;
				}
			}
		}
		ll d=gcd(v,n);
			if(d>1){
				while(n%d==0)n/=d;
				pollard_rho(n);
				pollard_rho(d);
				return ;
			}		
	}
}
void solve(void)
{
	for(int i=1;i<=k;i++,f.clear())
	{
		pollard_rho(M[i]);
		sort(f.begin(),f.end());
		int cnt=unique(f.begin(),f.end())-f.begin();
		vector<ll> e(cnt);
		for(int j=1;j<=m;j++)aa[j]=a[c[i]][j],bb[j]=b[j];
		bool flag=false;
		for(int j=0;j<cnt;j++)
		{
			for(int l=1;l<=m;l++)while(bb[l]%f[j]==0)bb[l]/=f[j],e[j]++;
			for(int l=1;l<=m;l++)while(aa[l]%f[j]==0)aa[l]/=f[j],e[j]--;
			if(e[j]<0){
				flag=true;
				break;
			}
		}
		if(flag){
			printf("-1\n");
			continue;
		}
		ll ansa=1,ansb=1,phi=M[i];
		for(int j=0;j<cnt;j++)phi-=phi/f[j];
		for(int j=1;j<=m;j++)ansa=(__int128)ansa*aa[j]%M[i];
		for(int j=1;j<=m;j++)ansb=(__int128)ansb*bb[j]%M[i];
		for(int j=0;j<cnt;j++)ansb=(__int128)ansb*qpow(f[j],e[j],M[i])%M[i];//把除多的补回来 
		ll rev=qpow(ansa,phi-1,M[i]);
		ll ans=(__int128)ansb*rev%M[i];
		printf("%lld\n",ans);
	}
	return ;
}
int main(void)
{
	srand(time(NULL));
	scanf("%lld%lld%lld",&n,&m,&k);
	for(int i=1;i<=m;i++)
	scanf("%lld",&b[i]);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	scanf("%lld",&a[i][j]);
	for(int i=1;i<=k;i++)
	scanf("%lld %lld",&c[i],&M[i]);
	solve();
}
MR素性检测算法 素数是除了自身和1以外,没有其它素数因子的自然数。自从欧几里得证明了有无穷个素数以后,人们就企图寻找一个可以构造所有素数的公式,寻找判定一个自然数是不是素数的方法。因为素数的地位非常重要。 阅读详情

相关推荐

费马小定理及MR素数判断

费马小定理及MR素数判断。

ZigZagK的博客 3105

素数检测算法

前言 今天做ACM的时候,遇到了素数的检测,检测一个范围内的素数的时候,如果用最简单的那种方法,超时严重,因此学习了一个新的素数检测算法——素数筛选法,这里也是跟大家分享一下 素数 素数的定义 一个大于1的整数,如果不能被除1和它本身之外的其它正整数整除,则是素数(又称质数) 合数的定义 一个大于1的整数,如果不是素数则是合数。其中能整除这个数的正整数叫做约数,不等于1也不等于合数...

系统运维 558

筛素数方法(二)—— 费马小定理及MR素数判断

  注明:本文中的x^y表示x的y次方   一、费马小定理 1.1 内容 若p为素数,a为正整数,且gcd(a,p)=1,则a^(p−1)≡1(mod p)。1.2 证明 因为p为素数,所以gcd(i,p)=1(1&lt;=i&lt;=p-1,i为整数),可推出①gcd((p-i)!,p)=1,又因为gcd(a,p)=1,所以gcd(i∗a,p)=1,则②没有一个i*a是p的倍数。  设a...

CXR的博客 2703

素数题目总结及mr判断素数

素数水题lv_16(大概是只需要打表加遍历,,,也不需要思考,也不会超时,更悲痛的是,换了个题干,结果做法一模一样,或者是微改,微到什么程度呢?大概是改改输出格式、输出内容吧!) *NUC1019 数素数 呵呵哒,看起来好像很有恐怖什么2的次幂啥的,都是虚晃一招,实际上求前缀和就好了 *哥德巴赫猜想集结……简直了,要不然找对数,要不然找最远的(从2开始遍历),要不然找最近的(从一半开始,偶数-...

雨潇的博客 764

特斯拉 Model 3解析(八)全面拆解特斯拉自动驾驶大脑:AP控制器硬核技术解析

算力极限:双FSD = 144 TOPS,专为AI推理优化。存储架构:LPDDR4 + NAND + NOR,保证高速/可靠启动。通信架构:以太网传视频,CAN传控制,TSN保障实时性。感知输入:多路摄像头 + 高速SerDes,满足全景感知。电源设计:功率模块+被动元件海洋,稳定性优先。功能安全:双芯片冗余 + GPS + 紧急呼叫,容错率极高。🎯 在我看来,特斯拉AP控制器就是一台“车载超算”,它在电源设计、存储架构和功能安全上远超一般新势力方案。

weixin_43199439的博客 1440

DOA估计算法从原理到仿真——CBF、Capon、MUSIC算法

从原理出发理解并实现经典的DOA估计算法

m0_55845774的博客 1万+

MR 素性检测 (快速幂+快速乘)

const int S=9; int qmul(int a, int b, int mod)//快速乘 { int c = a*b-(int)((long double)a*b/mod+0.5)*mod; return c<0 ? c+mod : c; } int qpow(int a,int b,int mod)//快速幂 { int ans=1,buff=a;...

codehappy123的博客 371

手把手教你搞定Pattern Recognition期刊的LaTeX投稿(附完整模板下载与避坑指南)

本文详细指导如何在Pattern Recognition期刊上使用LaTeX进行投稿,包括模板下载、环境配置、核心排版规范及投稿材料准备。特别强调期刊对格式的严格要求,如数学符号、图像引用等细节,并提供实用技巧和避坑指南,帮助作者高效完成投稿流程。

weixin_30876945的博客 394

费马小定理(MR素数探测法) v2.0

#include #include #include #include using namespace std; typedef long long LL; LL PowerMod(LL a, LL b, LL n) { if (b == 1) return a % n; LL x = PowerMod(a, b >> 1, n); x = x * x %

Gemini 740

死区补偿---学习笔记

最近调试中发现,死区补偿对电流谐波和电流带宽影响挺大,于是对死区补偿产生浓厚兴趣,找来几篇文章粗读并做一下笔记。 传统做法 无非就是根据电流方向补偿,假如svpwm计算出的A相理论导通实践为T1,死区时间是Td,则实际导通时间T = T1-Td(when ia >0 ),于是在svpwm计算出的导通时间T1的基础上加上Td。这样经过PWM模块后,实际的导通时间即为T1. 但存在两个难点(个人总结): 1,受电流检测精度影响,尤其是在过零点检测困难。 2,真实的二极管导通需要一定电压,并非..

圆桌骑士的博客 2万+

图自编码器(GAE)与变分图自编码器(VGAE)

在学习图自编码器之前先了解一下自编码器与变分自编码器。

小鱼的小窝 1万+

素性测试

所谓素性测试是检测一个数是否为素数的测试。而对素数的研究是有很长一段历史,把素数的东西写成一本书的话也许得上千页,而现代密码学又加深了科研工作者对素数的研究,今天就以输出100以内的素数的为例,讲讲素性测试的几种方法。 1.试除法 这可能是每个学过计算机的朋友都敲过的代码,原理就是从判断2到sqrt(n)或者n/2能不能整除n,若能整除就不是素数。 代码清单: public cla...

nayao-net 752

电力系统分析 | Matlab实现源荷场景生成---蒙特卡洛法场景生成启发式同步回带削减

电力系统分析 | Matlab实现源荷场景生成---蒙特卡洛法场景生成启发式同步回带削减

前程算法屋的博客 812

米勒拉宾算法——素性测试

米勒拉宾素性测试 对于一个数n,如果想要判断它是否为素数,常规的方法为试除法。即,让n依次除以2到sqrt(n)以内的整数。如果有出现除尽的情况,则为合数。 该方法的时间复杂度为O(sqrt(n))在面对n为长整型的时候有可能超出时间要求。因此普遍采用米勒拉宾算法进行素性判定。在此之前介绍一种伪素数判定方法——小费马定理。 小费马定理为:若有素数p,则对任意的数a( a为正整数 ,且a &l...

kuangle的博客 1万+

2025年新发表的语音大模型全双工模型/框架/技术

参考该论文,给出2025年新发表的全双工模型或框架或技术下面这份清单专挑、且与“全双工语音对话/同步对话(边听边说、可打断、回馈/相槌、重叠语音)”直接相关的。我也结合你提到的的四大维度(暂停处理、相槌、顺滑换手、打断管理)来点出它们各自的贡献点,便于后续评测与对比。

u013250861的博客 630

ROS机器人里程计模型

3.5 移动机器人系统模型 相信大家的机器人平台STM32端底层控制和机器人urdf建模都已经顺利完成了,在正式开始ros端编写机器人启动功能包之前,我们还不得不学习一些必要的理论知识。别担心数学不好,这里基本都是高中数学。下面我们开始,Are you ready? 没准备好也开始了。 3.5.1 常用坐标系系统模型 在移动机器人技术研究中,最为常用的坐标系统是笛卡尔坐标系统。而在SLAM算法研究中,有如下几个比较常见的笛卡尔坐标系统,它们分别为机器人坐标系XR YR OR 、传感器坐标系XS YS OS

「小白学移动机器人」一个专注分享移动机器人相关知识的公众号! 1万+

米勒拉宾素数测试

ll quick_pow(ll a,ll b,ll r)//快速幂  {     ll ans = 1;     while(b)     {         if(b&1)ans=(ans*a)%r;         a = (a*a)%r;         b>>=1;     }     return ans; } bool Miller_Rabbin(int n,in

Nemaleswang的博客 1630

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【算法编程】基于Miller-Rabin的大素数测试

基本原理: 费尔马小定理:如果p是一个素数,且0则a^(p-1)%p=1.        利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,通过计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n  很可能是素数. 二次探测定理:如果p是一个素数,且0则方程x^2%p=1的解为:x=1或x=p-1.        利用二次探测定理,可以再利

青峰碧陋室 4097

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Miller Rabin素数测试 复习小记

Preface为什么是复习小记?因为忘了个精光QAQMiller Rabin素数测试基于以下两个原理:费马小定理若(a,p)=1(a,p)=1且pp是质数,则ap−1≡1(modp)a^{p-1}≡1\ (mod\ p),反之不一定成立二次探测定理若pp是素数,则x2≡1(modp)x^2≡1\ (mod\ p)的解只有x=1x=1或x=p−1(−1)x=p-1(-1) 也即如果x2≡1

LYD729 834

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

斐波那契数列以及Catalan数通项公式的推导

1、斐波那契数列的通项公式推导: 已知斐波那契数列的递推公式为f(n)=f(n−1)+f(n−2)f(n)=f(n-1)+f(n-2)f(n)=f(n−1)+f(n−2)且f(0)=0,f(1)=1f(0)=0,f(1)=1f(0)=0,f(1)=1。 设斐波那契数列的生成函数为F(x)F(x)F(x),F(x)=∑i=0nf(i)xiF(x)=\sum_{i=0}^nf(i)x^iF(x)=∑i=0n​f(i)xi。 ...

WedsonLin的博客 1947

二次剩余与Cipolla算法

二次剩余与Cipolla算法 若存在x,使得 x2≡a(modp)x^2\equiv a \pmod{p}x2≡a(modp) 成立且a不是p的倍数,则称a为模p的二次剩余。 下文只讨论p为奇素数的情况。 1、模p二次剩余的个数 对于一个素数p,p的二次剩余有(p-1)/2个,非二次剩余有(p-1)/2个。 因为有(p−x)2≡x2(modp)(p-x)^2\equiv x^2 \pmod{p}(p−x)2≡x2(modp),所以在[1,(p-1)/2]范围内即可得到模p的所有二次剩余数,只需要证明在[1,

WedsonLin的博客 899

Timus 1673(反欧拉函数)

Timus 1673(反欧拉函数) 题目链接 有题意可知,设第i个教授掌管的实验室编号为index,则满足index≡i(modN)index\equiv i\pmod Nindex≡i(modN);对于第k个同学,只去编号为index′=kx(k≥1)index'=kx(k\ge 1)index′=kx(k≥1)的实验室。如果第k个同学要获得考试资格,则满足如下同余方程组 {kx1≡1(modN)kx2≡2(modN)...kxN≡N(modN)\left\{\begin{matrix} kx_1\eq

WedsonLin的博客 663

Miller-Rabin随机性素数测试方法

关于素数测试 素数测试就是判断一个整数是素数还是合数。一般判断素数p的方式是通过判断2到根号p内的整数是否可以整除p来实现。时间复杂度为O(p1/2)。如果p是一个m位二进制整数,m=floor(Ig(p+1)),O(p1/2)=O(2m/2)。 然而对于大整数而言,这样的时间复杂度显然是不可以接受的。 费马小定理:if n is prime   ∀a∈Zn∗ , an−1≡1(modn)if\space n\space is\

WedsonLin的博客 635

Codeforces Round #707 Div. 2/C Going Home

Codeforces Round #707 Div. 2/C Going Home 题意:在长度为N的数组A中找出满足ax+ay=aw+aza_x+a_y=a_w+a_zax​+ay​=aw​+az​的一组x,y,w,zx,y,w,zx,y,w,z,要求它们之间两两不同。(N≤2e5,1≤a[i]≤2.5e6(N\le 2e5,1\le a[i]\le 2.5e6(N≤2e5,1≤a[i]≤2.5e6 。 最简单直接的算法就是枚举序列中的(i,j)(i,j)(i,j)然后加以判断,这样做的做法是O(n2)O

WedsonLin的博客 610
上一篇: Timus 1673(反欧拉函数)
下一篇: 关于树状数
WedsonLin
博客等级 码龄7年 1粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值