分解质因数
引入
给定一个正整数
考虑朴素算法,因数是成对分布的,
当
朴素算法
最简单的算法即为从
=== "C++"
```cpp
list<int> breakdown(int N) {
list<int> result;
for (int i = 2; i * i <= N; i++) {
if (N % i == 0) { // 如果 i 能够整除 N,说明 i 为 N 的一个质因子。
while (N % i == 0) N /= i;
result.push_back(i);
}
}
if (N != 1) { // 说明再经过操作之后 N 留下了一个素数
result.push_back(N);
}
return result;
}
```
=== "Python"
```python
def breakdown(N):
result = []
for i in range(2, int(sqrt(N)) + 1):
if N % i == 0: # 如果 i 能够整除 N,说明 i 为 N 的一个质因子。
while N % i == 0:
N = N // i
result.append(i)
if N != 1: # 说明再经过操作之后 N 留下了一个素数
result.append(N)
return result
```
我们能够证明 result
中的所有元素均为 N
的素因数。
result
中均为 首先证明元素均为 N % i == 0
满足时,result
发生变化:储存 result
若在 push N
其次证明 result
中均为素数。我们假设存在一个在 result
中的合数 while(N % k1 == 0) N /= k1
,即让 N
没有了素因子 N
和
值得指出的是,如果开始已经打了一个素数表的话,时间复杂度将从
例题:CF 1445C
Pollard Rho 算法
引入
而下面复杂度复杂度更低的 Pollard-Rho 算法是一种用于快速分解非平凡因数的算法(注意!非平凡因子不是素因子)。而在此之前需要先引入生日悖论。
生日悖论
不考虑出生年份(假设每年都是 365 天),问:一个房间中至少多少人,才能使其中两个人生日相同的概率达到
解:假设一年有
设 k 个人生日互不相同为事件
至少有两个人生日相同的概率为
由不等式
然而我们可以得到一个不等式方程,
将
当
考虑一个问题,设置一个数据
构造伪随机函数
我们通过
随机取一个
举个例子,设
可以发现数据在 3 以后都在 11,23,31 之间循环,这也是
如果将这些数如下图一样排列起来,会发现这个图像酷似一个
优化随机算法
最大公约数一定是某个数的约数,即
将生日悖论应用到随机算法中,伪随机数序列中不同值的数量约为
于是就得到了一个新序列
假设存在两个位置
性质
我们期望枚举
下面介绍两种实现算法,两种算法都可以在
实现
Floyd 判环
假设两个人在赛跑,A 的速度快,B 的速度慢,经过一定时间后,A 一定会和 B 相遇,且相遇时 A 跑过的总距离减去 B 跑过的总距离一定是圈长的 n 倍。
设
我们每次令
=== "C++"
```cpp
ll Pollard_Rho(ll N) {
ll c = rand() % (N - 1) + 1;
ll t = f(0, c, N);
ll r = f(f(0, c, N), c, N);
while (t != r) {
ll d = gcd(abs(t - r), N);
if (d > 1) return d;
t = f(t, c, N);
r = f(f(r, c, N), c, N);
}
return N;
}
```
=== "Python"
```python
def Pollard_Rho(N):
c = random.randint(0, 32767) % (N - 1) + 1
t = f(0, c, N)
r = f(f(0, c, N), c, N)
while t != r:
d = gcd(abs(t - r), N)
if d > 1:
return d
t = f(t, c, N)
r = f(f(r, c, N), c, N)
return N
```
倍增优化
使用
我们每过一段时间将这些差值进行
对于一个数
贡献者:@383494@TianKong_y@Menci@WenzelTian@CCXXXI@Zhikai@Saisyc@Bubbleioa@kenlig@Great-designer
本页面最近更新:2/3/2023, 12:00:00 AM,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用