目录

问题

给定n,要求对n质因数分解

普通的试除法已经不能应用于大整数了,我们需要更快的算法

流程

大概就是找出\(n=c*d\)

如果\(c\)是素数,结束,不是继续递归处理。

具体一点的话

1.先对n进行\(miller\_rabin\)测试,是素数就直接结束了

如果不会的话,看我前篇博客的介绍吧

为何还要多写个\(miller\_rabin\),他没有非平凡因子,他要保证复杂度?

2.随机基底a和c,生成序列\(x_{0}=a,x_{i}=x_{i-1}^{2}+c(mod n)\),可以认为\({x_{i}}\)是有循环节的随机序列(rho就是密度的那个符号,长得很像是不是)

3.若出现\((x_{i}-x_{2i+1},n)≠1\),停止算法,令\(d=(x_{i}-x_{2i+1},n)\),若\(d≠n\),那d就是n的非平凡因子,n被分为d和n/d相乘的结果,递归下去继续分解

4.若d=n,重选基底a和c,重复过程(出现循环了)

刘汝佳先生说:想象一下,假设有两个小孩子在一个“可以无限向前跑”的跑道上赛跑,同时出发。但其中一个小孩的速度是另一个的两倍。如果跑道是直的,跑得快的小孩永远在前面;但如果跑道有环,则跑得快的小孩将“追上”跑得慢的小孩。

算法复杂度\(O(n^{ \frac {1}{4} }*pro)\)

具体的我也不知道咋证

代码

#include <bits/stdc++.h>

using namespace std;
const int maxn = 10005;
typedef long long LL; LL fpm(LL a, LL k, LL p) //calc a^k % p
{
LL res = 1;
for (; k ; k >>= 1, a = a * a % p)
if (k & 1) res = a * res % p;
return res;
} int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
bool detective(LL a, LL n)
{
int r = 0; LL d = n - 1; // n - 1 = 2 ^ r * d
while (d % 2 == 0) d >>= 1, ++r;
for (LL x = fpm(a, d, n), y; r ; r--)
{
y = x * x % n;
if (y == 1)
{
if (x == 1) return true;
if (x == n - 1) return true;
return false;
}
x = y;
}
return false;
}
bool miller_rabin(LL n)
{
for (int i = 0; i < 10; i++)
{
if (n == prime[i]) return true;
if (n % prime[i] == 0) return false;
if (!detective(prime[i], n)) return false;
}
return true;
} vector<LL> res;
int irand() {return rand() << 15 ^ rand();}
LL irand(LL n) {return (((LL) irand()) << 30 ^ irand()) % n;}
LL mul(LL a, LL b, LL n) {return (a * b - (LL) ((long double) a * b / n + 1e-9) * n) % n;}
LL rho(LL n)
{
LL a = irand(n), c = irand(n);
LL x = a, y = (mul(a, a, n) + c) % n;
LL z = x > y ? x - y: y - x;
LL d = __gcd(z, n);
while (d == 1)
{
x = (mul(x, x, n) + c) % n;
y = (mul(y, y, n) + c) % n;
y = (mul(y, y, n) + c) % n;
z = x > y ? x - y: y - x;
d = __gcd(z, n);
}
return d;
}
void pollard_rho(LL n)
{
if (n == 1) return ;
if (miller_rabin(n)) {res.push_back(n); return ;}
LL d = n; while (d == n) d = rho(n);
pollard_rho(d); pollard_rho(n / d);
}
int main()
{
pollard_rho(997 * 131ll * 6ll * 50ll * 79ll * 97 * 12132);
for (auto x: res) cerr << x << " " ;
}

生日悖论

(当然,我们这里的一年是稳定365天,和我们不一样)

23个人中至少有一对两个人生日相同的概率在一半以上,感觉不可思议吧,与我们自我感觉的有很大差异,其实,当我们看到“有人生日相同”时,下意识地会用“与我生日相同”去推测,直觉就让我们直觉产生了“两人生日相同”概率很小。理性计算的结果与日常经验产生了如此明显的矛盾,所以叫做“生日悖论”。

可以说,直觉没有错,错的是我们没有正确地去理解问题。因此,当我们剥开直觉的谎言,看清事实的那一刻,才会觉得如此不可思议。

我们的问题是“任意两个人的生日相同的概率”(所以要理性分析呀qwq)。

我们讨论两个人生日相同的情况。

总概率是365*365,生日不同的情况\(365*364\)

那生日相同的情况就是 \(\frac{365*365-365*364}{365*365}=\frac{1}{365}\)

四个人同理\(\frac{365^4-\frac{365!}{361!}}{365^4}\)

再大一点可以用long double 计算,可以算出23人时概率就大于一半了

end

鸣谢

Pollard Rho大质数分解学习笔记的更多相关文章

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

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

  2. POJ 1811 Prime Test (Pollard rho 大整数分解)

    题意:给出一个N,若N为素数,输出Prime.若为合数,输出最小的素因子.思路:Pollard rho大整数分解,模板题 #include <iostream> #include < ...

  3. 整数(质因子)分解(Pollard rho大整数分解)

    整数分解,又称质因子分解.在数学中,整数分解问题是指:给出一个正整数,将其写成几个素数的乘积的形式. (每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数.) .试除法(适用于范 ...

  4. HDU 3864 D_num Miller Rabin 质数推断+Pollard Rho大整数分解

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=3864 题意:给出一个数N(1<=N<10^18).假设N仅仅有四个约数.就输出除1外的三个约 ...

  5. 大数据 -- kafka学习笔记:知识点整理(部分转载)

    一 为什么需要消息系统 1.解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多 ...

  6. angular这个大梗的学习笔记

    angular定义一个模块(module)及控制器(controller)的局部声明方法: var app=angular.module("Myapp",[]); myapp.co ...

  7. Hadoop学习笔记一

    云帆大数据视频学习笔记,记录如下. 一.主机名设置的规范 /etc/hosts文件中添加如下的记录: 192.168.1.128 hadoop-yarn.cloudyhadoop.com had-ya ...

  8. 不错的Spring学习笔记(转)

    Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是s ...

  9. [学习笔记]Pollard-Rho

    之前学的都是假的 %%zzt Miller_Rabin:Miller-Rabin与二次探测 大质数分解: 找到所有质因子,再logn搞出质因子的次数 方法:不断找到一个约数d,递归d,n/d进行分解, ...

随机推荐

  1. sqlserver备份还原数据库时报占用错误

    .做项目时遇到这种情形:原来的test_dev数据库,想复制出test_ft供测试用.此时备份test_dev出test_backup文件,想直接还原成test_ft时会报占用错误. 还原数据库:Th ...

  2. java的移位运算详解(举例说明)

    1)java中无符号右移:>>>,下面是一个int型的负数,然后每次移动一位. int k = -0x123;System.out.println(Integer.toBinaryS ...

  3. springboot的默认访问路径

    注意:默认配置的/**映射到/static(或/public ,/resources,/META-INF/resources) 当请求/index.html的时候,Spring MVC 会在/stat ...

  4. Python二分法查找

    1.1二分前提是有序,,否则不可以2分,2分查找的时间复杂度是O(log n):排序后二分查找到适当的位置插入数值 lst = [37,99,73,48,47,40,40,25,99,51] def ...

  5. ps 证件照(1,2寸)

    制作证件照      9*9打印 1,1寸  图片裁剪 2, 2寸 图片裁剪 3,将裁剪完成后的图片选择添加画布  Alt Ctrl  c 将高和宽各加20px  ,背景选择白色 4,将得到的带有白色 ...

  6. html5-常用的3个基本标签

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  7. hive的find_in_set函数

    集合查找函数: find_in_set语法: find_in_set(string str, string strList) 返回值: int说明: 返回str在strlist第一次出现的位置,str ...

  8. flask 重定向到上一个页面,referrer、next参数

    重定向会上一个页面 在某些场景下,我们需要在用户访问某个url后重定向会上一个页面,比如用户点击某个需要登录才能访问的连接,这时程序会重定向到登录页面,当用户登录后比较合理的行为是重定向到用户登录前浏 ...

  9. 转:【专题八】P2P编程

    引言: 前面的介绍专题中有朋友向我留言说介绍下关于P2P相关的内容的,首先本人对于C#网络编程也不是什么大牛,因为能力的关系,也只能把自己的一些学习过程和自己的一些学习过程中的理解和大家分享下的,下面 ...

  10. java获取前一天时间SimpleDateFormat,java判断某个时间段

    java获取前一天时间SimpleDateFormat SimpleDateFormat predf = new SimpleDateFormat("yyyy-MM-dd"); D ...