首先,这个整数的标准分解非常的显然易见对吧:

一般我们要把一个数分解成这个样子我们可以这样写:

 #include<cstdio>
int p[],w[],k;
void factorize(int n)
{
for(int i=;i*i<=n;i++)
if(n%i==)
{
p[++k]=i;
while(n%i==)
n/=i,w[k]++;
}
if(n!=)
p[++k]=n,w[k]=;
}
int main()
{
int n;
scanf("%d",&n);
factorize(n);
for(int i=;i<k;i++)
printf("%d^%d*",p[i],w[i]);
printf("%d^%d",p[k],w[k]);
}

由于是分解质数,而且质数除了2之外都是奇数,所以可以在枚举i的时候每次i+=2

例题:ABC142D(手边没有什么好题了,只是因为最近做到了它2333)

要找互质的公因数,就相当于找最大公因数的最多互质的因数。(这个表述...相信你们能懂

之前写一直T了,于是找了另外一种方法,后面才发现之前的哪里有问题

 #include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
#define N 100005
#define ll long long
#define MOD 1000000007
ll x,y;
map<ll,bool> vis;
ll p[N];
int pn;
ll gcd(ll a,ll b)
{
if(b==) return a;
else return gcd(b,a%b);
}
int main()
{
scanf("%lld %lld",&x,&y);
ll d=gcd(x,y);
int ans=;
if(d%==) ans++;
while(d%==)
d/=;
for(ll i=;i*i<=d;i+=)//写成i<=d/i就可以不开ll 否则不开ll就会乘爆 然后T掉
if(d%i==)
{
ans++;
while(d%i==)
d/=i;
}
if(d!=) ans++;
printf("%d\n",ans);
return ;
}

就是我注释的那个地方,要注意那样的BUG了

最后采用了这种写法:

 #include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<cmath>
using namespace std;
#define N 100005
#define ll long long
#define MOD 1000000007
ll x,y;
map<ll,bool> vis;
ll p[N];
int pn;
vector<ll>st;
ll gcd(ll a,ll b)
{
if(b==) return a;
else return gcd(b,a%b);
}
bool is_prime(ll x)
{
if(x==) return ;
if(x==||x==) return ;
if(x%!=&&x%!=) return ;
int s=sqrt(x);
for(int i=;i<=s;i+=)
if(x%i==||x%(i+)==)
return ;
return ;
}
int solve(ll n)
{
int ans=;
if(n==) return ;
ll i=;
while(i<n)
{
if(is_prime(n))
{
st.push_back(n);
if(vis[n]==)ans++;
vis[n]=;
return ans;
}
for(int i=;i<n;i++)
{
if(n%i==)
{
st.push_back(i);
if(vis[i]==)ans++;
vis[i]=;
n/=i;
break;
}
}
}
st.push_back(n);
if(vis[n]==)ans++;
vis[n]=;
return ans;
}
int main()
{
scanf("%lld %lld",&x,&y);
ll d=gcd(x,y);
printf("%d\n",solve(d));
return ;
}

其实感觉和上面的做法差不多,直接看也就能看懂,但是网上据说是$n^{1/4}$的复杂度,那么还是了解一下,也没有什么坏处。(对于这道题来说其实不需要存因数的啦)

关于is_prime的素数判断,还是说一下吧。

如果不加这个判断,那么在$n$变成一个很大的质数的时候,这个算法就会退化到$O(n)$级别。

对于每一个$>=5$的数可以表示为$6x-1$(也相当于$6x+5$),$6x$,$6x+1$,$6x+2$,$6x+3$,$6x+4$,$6x+5$中的一种。

而$6x$,$6x+2=2(3x+1)$,$6x+3=3(x+1)$,$6x+4=2(3x+2)$,都不可能是素数。

所以我们对于一个数n,直接先判断它模$6$是否余$5$或余$1$,不是的话直接返回false

但是是的话也不一定是素数,还要再判断一下。

每个数都能进行质因数分解,所以我们只要判断用它除前面的素数能否除尽就可以了.

$6x+1$,$6x+5$这样的数显然不可能除的尽$2$和$3$,所以我们从$5$开始判断。

下一个除以$7$,按照上面的讨论,下一个为$11$和$13$。

网上有人说,以此类推,可以把步长增加到$6$来加快运行速度。

不知道怎么证明,但是验证了一下是对的。(怎么感觉好水...)

update2019.10.9 关于把步长增加到$6$

发现自己好傻啊

前面已经说了,3以后的质数都是除以6余1或者5的数

那么连续的两个质数差为2

当然,除以6余1或者5的数不一定都是质数,不过这没有关系,我们不一定要让除数是一个质数。


莫名其妙地就干完了这篇博客。

写得好水呀。

嘤嘤嘤我在干什么。

快速质因数分解及素性测试&ABC142D的更多相关文章

  1. PAT 甲级 1059 Prime Factors (25 分) ((新学)快速质因数分解,注意1=1)

    1059 Prime Factors (25 分)   Given any positive integer N, you are supposed to find all of its prime ...

  2. 对于n!的快速质因数分解

    N!的阶乘的质因数分解 对于N的阶乘 比如8! 我们要算其中一个质因数出现次数 我们注意到 8!=1 2 3 4 5 6 7 8 1 1 1 1 2的倍数出现的次数8/2=4 1 1 4的倍数出现的次 ...

  3. [学习笔记] Miller-Rabin质数测试 & Pollard-Rho质因数分解

    目录 Miller-Rabin质数测试 & Pollard-Rho质因数分解 Miller-Rabin质数测试 一些依赖的定理 实现以及正确率 Pollard-Rho质因数分解 生日悖论与生日 ...

  4. 关于Miller-Rabin与Pollard-Rho算法的理解(素性测试与质因数分解)

    前置 费马小定理(即若P为质数,则\(A^P\equiv A \pmod{P}\)). 欧几里得算法(GCD). 快速幂,龟速乘. 素性测试 引入 素性测试是OI中一个十分重要的事,在数学毒瘤题中有着 ...

  5. Miller-Rabin 素性测试 与 Pollard Rho 大整数分解

    \(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...

  6. Miller-Rabbin 素性测试 和 Pollard_rho整数分解

    今天学习一下Miller-Rabbin  素性测试 和 Pollard_rho整数分解. 两者都是概率算法. Miller_Rabbin素性测试是对简单伪素数pseudoprime测试的改进. (ps ...

  7. POJ 1811 Prime Test 素性测试 分解素因子

    题意: 给你一个数n(n <= 2^54),判断n是不是素数,如果是输出Prime,否则输出n最小的素因子 解题思路: 自然数素性测试可以看看Matrix67的  素数与素性测试 素因子分解利用 ...

  8. 质因数分解的rho以及miller-rabin

    一.前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题.我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法, ...

  9. Miller-Rabin素性测试

    有时候我们想快速的知道一个数是不是素数,而这个数又特别的大导致 $O(\sqrt n)$ 的算法也难以通过,这时候我们可以对其进行 Miller-Rabin 素数测试,可以很大概率测出其是否为素数. ...

随机推荐

  1. java笔记1-面向对象思想

    合适的方法放在合适的类之中. 设计中,分解出应该具有哪些对象(面向对象),不要再想步骤了(这是面向过程).设计过程: step1:问题中有哪些类和对象(找名词,之后区分是类还是属性) step2:这些 ...

  2. 【Wince-DataTable填充ListView】DataTable的数据填充到ListView控件,适用.Net2.0

    在开发WinCE6.0程序的时候,要把DataTable的数据显示到ListView控件上,无法使用绑定, 只能使用循环遍历. 思路:外循环遍历行,内循环遍历列 //DataTable:dt2 //L ...

  3. 18-Node.js学习笔记-Express-请求处理-构建模块化路由

    构建模块化路由 const express = require('express') //创建路由对象 const home = express.Router(); //将路由和请求路径进行匹配 ap ...

  4. linux运维、架构之路-K8s应用

    一.Deployment         k8s通过各种Controller管理Pod的生命周期,为了满足不同的业务场景,k8s提供了Deployment.ReplicaSet.DaemonSet.S ...

  5. linux运维、架构之路-K8s滚动更新及回滚

    一.滚动更新        应用程序一次只更新一小部分副本,更新成功后,再更新更多的副本,最终完成所有副本的更新. 滚动更新的优点:零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 1. ...

  6. Confluence 6 Office 和 PDF 文件

    插入一个文件到页面中是能够让你将有用的文件,电子表格,幻灯片或者其他可用的文件在你小组中进行分享的好方法. 针对所有的文件类型,你可以选择以链接方式插入一个文件.缩略图将会对文档的内容进行预览同时可以 ...

  7. Linux命令-文件传输

    Linux命令-文件传输 Linux lprm命令 Linux lprm命令用于将一个工作由打印机贮列中移除 尚未完成的打印机工作会被放在打印机贮列之中,这个命令可用来将常未送到打印机的工作取消.由于 ...

  8. 在线PDU格式编码/解码

    在线PDU格式编码/解码 使用GSM/GPRS AT指令发送中文短信,汉字时,需要先将短信内容编码成PDU格式,然后通过AT+CMGS AT+CMGW等指令发送.     注意:需要先通过AT+CMG ...

  9. 图解数据库中的join操作

    1.所有的join都从cross join衍生而来 2.所有join图示 转自Say NO to Venn Diagrams When Explaining JOINs

  10. web长时间不激活 终止用户回话

    参考资料: http://web.jobbole.com/89072/ http://www.cnblogs.com/1175429393wljblog/p/5570606.html http://w ...