快速质因数分解及素性测试&ABC142D
首先,这个整数的标准分解非常的显然易见对吧:

一般我们要把一个数分解成这个样子我们可以这样写:
#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的更多相关文章
- 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 ...
- 对于n!的快速质因数分解
N!的阶乘的质因数分解 对于N的阶乘 比如8! 我们要算其中一个质因数出现次数 我们注意到 8!=1 2 3 4 5 6 7 8 1 1 1 1 2的倍数出现的次数8/2=4 1 1 4的倍数出现的次 ...
- [学习笔记] Miller-Rabin质数测试 & Pollard-Rho质因数分解
目录 Miller-Rabin质数测试 & Pollard-Rho质因数分解 Miller-Rabin质数测试 一些依赖的定理 实现以及正确率 Pollard-Rho质因数分解 生日悖论与生日 ...
- 关于Miller-Rabin与Pollard-Rho算法的理解(素性测试与质因数分解)
前置 费马小定理(即若P为质数,则\(A^P\equiv A \pmod{P}\)). 欧几里得算法(GCD). 快速幂,龟速乘. 素性测试 引入 素性测试是OI中一个十分重要的事,在数学毒瘤题中有着 ...
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
- Miller-Rabbin 素性测试 和 Pollard_rho整数分解
今天学习一下Miller-Rabbin 素性测试 和 Pollard_rho整数分解. 两者都是概率算法. Miller_Rabbin素性测试是对简单伪素数pseudoprime测试的改进. (ps ...
- POJ 1811 Prime Test 素性测试 分解素因子
题意: 给你一个数n(n <= 2^54),判断n是不是素数,如果是输出Prime,否则输出n最小的素因子 解题思路: 自然数素性测试可以看看Matrix67的 素数与素性测试 素因子分解利用 ...
- 质因数分解的rho以及miller-rabin
一.前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题.我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法, ...
- Miller-Rabin素性测试
有时候我们想快速的知道一个数是不是素数,而这个数又特别的大导致 $O(\sqrt n)$ 的算法也难以通过,这时候我们可以对其进行 Miller-Rabin 素数测试,可以很大概率测出其是否为素数. ...
随机推荐
- 【hiho1715】树的联通问题
题目大意:给定一棵 1~n 标号的树.Tree[L,R]表示最少需要选择的边的数量使得 L~R 号点两两连通.求: \[ \sum_{L=1}^{n} \sum_{R=L}^{n} \operator ...
- 我的前端组件 ---- 16:9固定宽高比例的div
目标:遇到一个需求,让图片在页面中,不管宽度如何变化.宽高保持16:9的比例. 实现: 方法一:这也是比较经典的一个方法,利用padding-bottom来实现. <!DOCTYPE html& ...
- JAVA基础编程之打印99乘法表
需求:打印9*9乘法表 技术考核: 1.for嵌套循环 代码: // 打印99乘法表 public static void print99Table() { System.out.println(&q ...
- 【Linux学习一】命令行CLI、BASH的基本操作
●操作系统的基本结构 操作系统的基本结构通过Kernel(内核)和Shell(壳)构成.常见的Shell分为GUI和CLI GUI 图形方面的shell ------〉windows .mac osC ...
- MySQL--关于MySQL练习过程中遇到的AVG()函数处理空值的问题
最近正准备面试,所以本来不怎么熟悉的SQL语句迫切需要练习,学习一下 在此感谢 笨鸟先飞-天道酬勤 大佬的博客:https://blog.csdn.net/dehu_zhou/article/deta ...
- 【BZOJ2459】 [BeiJing2011]神秘好人
Description 有一个神秘好人跟Bdcxq玩一个游戏,如果Bdcxq成功完成了这个游戏,那么他将会得到一件礼物. 这个游戏是这样的: 有一个梯子形的图如下,每条边都有一个权值. 神秘好人一开始 ...
- VUE里面的$(this)
我们很多时候需要用到列表点击其中的某个有相对的事件发生,那就拿用到$(this),但是在vue里面,直接写$(this)获取不到指定的元素,所以我就用的下面这种写法 <div v-for=&qu ...
- [CSP-S模拟测试]:打表(猜测题意+结论)
题目传送门(内部题139) 输入格式 第一行两个整数$k,ans$,表示内存地址$A$的位数,以及答案所在的内存地址. 接下来一行$2^k$个整数,分别表示内存地址$0...2^k-1$上的值. 输出 ...
- Spring boot之使用thymeleaf
操作步骤 (1)在pom.xml中引入thymeleaf; (2)如何关闭thymeleaf缓存 (3)编写模板文件.html (4)编写访问模板文件controller 在pom.xml中引入thy ...
- C++入门经典-例2.15-逗号表达式的应用
1:代码如下: // 2.15.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include<iostream> using na ...