luogu P4718 【模板】Pollard-Rho算法(贴代码)
嘟嘟嘟
从标题中能看出来,我只是想贴一个代码。
先扯一会儿。
前几天模拟考到了这东西,今天有空就学了一下。
到网上找资料,发现前置技能是miller-rabin筛法,于是我还得先学这么个东西。
学miller-rabin的话不得不推荐这两篇文章:
大数质因解:浅谈Miller-Rabin和Pollard-Rho算法
素数与素性测试(Miller-Rabin测试)
但是我还是看了好几遍才懂……
至于pollard-rho这东西,还是上面的第一篇博客,以及这一篇A Quick Tutorial on Pollard's Rho Algorithm(不是英文)。
但是某谷的板子特别毒瘤,因为他卡常。
首先得把龟速快速乘改成\(O(1)\)的。
顺便说一下,\(O(1)\)的快速乘的原理就是用\(a * b \ \ mod \ \ n = a * b - \lfloor \frac{a * b}{n} \rfloor * n\)这个式子。然后因为什么自然溢出后溢出的位的差只可能是0或1,所以判断一下这个结果是否小于0(这里我是真不懂)。
还有一点就是这种floyd判圈法也过不了,于是我又找到了一个相对好理解的倍增的pollard-rho,快的吓人。具体看代码吧。
剩下的就是一些玄学的细节了,代码里也有注释。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<ctime>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
//const int maxn = ;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = (ans << 1) + (ans << 3) + ch - '0'; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
ll n, Max = 0;
In ll mul(ll a, ll b, ll mod)
{
ll d = (long double)a / mod * b + 1e-8; //还必须是long double……double精度不够
ll r = a * b - d * mod;
return r < 0 ? r + mod : r;
}
In ll quickpow(ll a, ll b, ll mod)
{
ll ret = 1;
for(; b; b >>= 1, a = mul(a, a, mod))
if(b & 1) ret = mul(ret, a, mod);
return ret;
}
In bool test(ll a, ll d, ll n)
{
ll t = quickpow(a, d, n);
if(t == 1) return 1;
while(d != n - 1 && t != n - 1 && t != 1) t = mul(t, t, n), d <<= 1;
return t == n - 1; //这里就不用判1了,因为只可能在while前出现1的情况
}
int a[] = {2, 3, 5, 7, 11};
In bool miller_rabin(ll n)
{
if(n == 1) return 0;
for(int i = 0; i < 5; ++i) //先粗筛一遍
{
if(n == a[i]) return 1;
if(!(n % a[i])) return 0;
}
ll d = n - 1;
while(!(d & 1)) d >>= 1;
for(int i = 1; i <= 5; ++i) //搞五遍
{
ll a = rand() % (n - 2) + 2;//x属于[2, n - 1]
if(!test(a, d, n)) return 0;
}
return 1;
}
In ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
In ll f(ll x, ll a, ll mod) {return (mul(x, x, mod) + a) % mod;}
const int M = (1 << 7) - 1; //我也不知道为啥M是这个数……
ll pollard_rho(ll n) //倍增版!减少gcd调用次数。(好像不用判环?)
{
for(int i = 0; i < 5; ++i) if(n % a[i] == 0) return a[i];
ll x = rand(), y = x, t = 1, a = rand() % (n - 2) + 2;
for(int k = 2;; k <<= 1, y = x)
{
ll q = 1;
for(int i = 1; i <= k; ++i)
{
x = f(x, a, n);
q = mul(q, abs(x - y), n);
// if(i >= M) //不等价!
if(!(i & M)) //超过了2 ^ 7,再用gcd
{
t = gcd(q, n);
if(t > 1) break; //找到了
}
}
if(t > 1 || (t = gcd(q, n)) > 1) break; //之所以再求一遍,是处理刚开始k < M的情况
}
return t;
}
In void find(ll x)
{
if(x == 1 || x <= Max) return;
if(miller_rabin(x)) {Max = max(Max, x); return;}
ll p = x;
while(p == x) p = pollard_rho(x);
while(x % p == 0) x /= p;
find(p); find(x);
}
int main()
{
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
srand(time(0));
int T = read();
while(T--)
{
n = read();
Max = 0;
find(n);
if(Max == n) puts("Prime");
else write(Max), enter;
}
return 0;
}
luogu P4718 【模板】Pollard-Rho算法(贴代码)的更多相关文章
- Pollard Rho算法浅谈
Pollard Rho介绍 Pollard Rho算法是Pollard[1]在1975年[2]发明的一种将大整数因数分解的算法 其中Pollard来源于发明者Pollard的姓,Rho则来自内部伪随机 ...
- Pollard Rho 算法简介
\(\text{update 2019.8.18}\) 由于本人将大部分精力花在了cnblogs上,而不是洛谷博客,评论区提出的一些问题直到今天才解决. 下面给出的Pollard Rho函数已给出散点 ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法
BZOJ 3667: Rabin-Miller算法 Time Limit: 60 Sec Memory Limit: 512 MBSubmit: 1044 Solved: 322[Submit][ ...
- 初学Pollard Rho算法
前言 \(Pollard\ Rho\)是一个著名的大数质因数分解算法,它的实现基于一个神奇的算法:\(MillerRabin\)素数测试(关于\(MillerRabin\),可以参考这篇博客:初学Mi ...
- BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)
题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330 (Luogu) https://www.luogu.org/prob ...
- 大整数分解质因数(Pollard rho算法)
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- 【快速因数分解】Pollard's Rho 算法
Pollard-Rho 是一个很神奇的算法,用于在 $O(n^{\frac{1}4}) $的期望时间复杂度内计算合数 n 的某个非平凡因子(除了1和它本身以外能整除它的数).事书上给出的复杂度是 \( ...
- 【Luogu】P4358密钥破解(Pollard Rho)
题目链接 容易发现如果我们求出p和q这题就差不多快变成一个sb题了. 于是我们就用Pollard Rho算法进行大数分解. 至于这个算法的原理,emmm 其实也不是很清楚啦 #include<c ...
- Miller-Rabin 素性测试 与 Pollard Rho 大整数分解
\(\\\) Miller-Rabin 素性测试 考虑如何检验一个数字是否为素数. 经典的试除法复杂度 \(O(\sqrt N)\) 适用于询问 \(N\le 10^{16}\) 的时候. 如果我们要 ...
随机推荐
- MyBatis从入门到放弃三:一对一关联查询
前言 简单来说在mybatis.xml中实现关联查询实在是有些麻烦,正是因为起框架本质是实现orm的半自动化. 那么mybatis实现一对一的关联查询则是使用association属性和resultM ...
- 一文看懂https如何保证数据传输的安全性的【转载、收藏】
一文看懂https如何保证数据传输的安全性的 一文看懂https如何保证数据传输的安全性的 大家都知道,在客户端与服务器数据传输的过程中,http协议的传输是不安全的,也就是一般情况下http是明 ...
- [android] 手机卫士设备管理权限锁屏
设备管理员 Device Admin 获取DevicePolicyManager对象,通过getSystemService(DEVICE_POLICY_MANAGER),设备策略管理器 调用Devic ...
- Maven远程仓库的各种配置
1.远程仓库的配置 在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他 ...
- 关于CSS3的filter(滤镜) 属性
修改所有图片或者元素的颜色为黑白 (100% 灰度) DOM{ -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */ filter: ...
- centos7学习笔记-安装后的一些配置
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 一.允许普通用户使用sudo root用户下运行 visudo 在root ALL=(ALL)ALL下面添加 username ...
- Python 类的祖宗--metaclass
1.Python 中一切事物都是对象 2.类都是 type 类的对象 类的两种申明方法 # 方法一: class Foo: def func(self): print(666) obj = Foo() ...
- Sybase SQL anywhere5.5
https://github.com/mono/old-code https://wiki.scn.sap.com/wiki/display/SQLANY/SQL+Anywhere+and+Micro ...
- BZOJ2705: [SDOI2012]Longge的问题(欧拉函数)
题意 题目链接 Sol 开始用反演推发现不会求\(\mu(k)\)慌的一批 退了两步发现只要求个欧拉函数就行了 \(ans = \sum_{d | n} d \phi(\frac{n}{d})\) 理 ...
- Docker 加速器设置
在部署完docker的时候我们需要进行在镜像源下载镜像的时候有时候会出现特别慢的情况(这是因为本地到源的网络出现了问题),这时候就需要使用加速器来对镜像进行下载了,在面咱们就聊一聊docker加速器的 ...