传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4802

【题解】

参考:http://www.matrix67.com/blog/archives/234

Millar-Rabin质数检验方法:

根据费马小定理,如果p是素数,a<p,那么有a^(p-1) mod p = 1。

直观想法我们直接取若干个a,如果都有一个不满足,那么p就是合数。

遗憾的是,存在Carmichael数:你无论取多少个a,有一个不满足,算我输。

比如:561 = 11*51就是一个Carmichael数。

那么就很江了啊。。我们需要改进算法。

首先有:如果p是素数,x是小于p的正整数,且x^2 mod p = 1,那么要么x=1,要么x=p-1

(这个废话,x=p-1模意义下等于x=-1)

然后我们可以展示下341满足2^340 mod 341 = 1,却不是素数(341=31*11)的原因:

2^340 mod 341 = 1

2^170 mod 341 = 1

2^85 mod 341 = 32

(32这个数很py啊怎么不等于340也不等于1啊。。这明显有交易嘛)

那么就能说明这个数不是素数。

如果是素数,一定是从p-1变到1,或是把所有2的次幂去除完,本来就等于1(这样平方完就一直是1了)

所以要么把所有2的次幂去除完,本来就等于1,要么存在某一个次幂=p-1(这样就正常多了)

这就是Millar-Rabin素数验证的二次探测。

应该来说Millar-Rabin算法也是挺好写的

其中mul(a,b,c)表示a*b%c(因为a*b会爆longlong,所以用快速加)

namespace Millar_Rabin {
const int Prime[] = {, , , , , , , , , , , , , };
const int PN = ; inline bool witness(int pr, ll res, int times, ll n) {
ll p = pwr2((ll)pr, res, n);
if(p == ) return ;
for (int i=; i<times; ++i) {
if(p == n-) return false;
if(p == ) return false;
p = mul(p, p, n);
}
return true;
} inline bool main(ll n) {
for (int i=; i<=PN; ++i) {
if(n == Prime[i]) return ;
if(n % Prime[i] == ) return ;
}
ll p = n-;
int times = ;
while(!(p&)) {
++times;
p >>= ;
}
for (int i=; i<=PN; ++i)
if(witness(Prime[i], p, times, n)) return false;
return true;
}
}

然后我们会检验素数了,现在要质因数分解。

好了下一个是Pollard-Rho算法:

如果现在拆分的是n:Pollard-Rho(n)

主要流程:Millar-Rabin判断是否质数,是返回,否就试图找出其中一个因子d,然后递归做Pollard-Rho(d)和Pollard-Rho(n/d)。

我猜你会说废话这谁都会。问题在于:试图找出其中一个因子d

参考:https://wenku.baidu.com/view/3db5c7a6ad51f01dc381f156.html?from=search

参考文章讲的非常详细了。。我就不细讲了qwq

所以这题就是分解因数,按照欧拉函数定义式求解即可。

# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h> using namespace std; typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + ;
const int mod = 1e9+; # define RG register
# define ST static inline ll mul(ll a, ll b, ll mod) {
ll ret = ;
a %= mod, b %= mod;
while(b) {
if(b&) {
ret = ret + a;
if(ret >= mod) ret -= mod;
}
a <<= ;
if(a >= mod) a -= mod;
b >>= ;
}
return ret;
} inline ll pwr2(ll a, ll b, ll mod) {
ll ret = ;
a %= mod;
while(b) {
if(b&) ret = mul(ret, a, mod);
a = mul(a, a, mod);
b >>= ;
}
return ret;
} inline ll gcd(ll a, ll b) {
return b== ? a : gcd(b, a%b);
} namespace Millar_Rabin {
const int Prime[] = {, , , , , , , , , , , , , };
const int PN = ; inline bool witness(int pr, ll res, int times, ll n) {
ll p = pwr2((ll)pr, res, n);
if(p == ) return ;
for (int i=; i<times; ++i) {
if(p == n-) return false;
if(p == ) return false;
p = mul(p, p, n);
}
return true;
} inline bool main(ll n) {
for (int i=; i<=PN; ++i) {
if(n == Prime[i]) return ;
if(n % Prime[i] == ) return ;
}
ll p = n-;
int times = ;
while(!(p&)) {
++times;
p >>= ;
}
for (int i=; i<=PN; ++i)
if(witness(Prime[i], p, times, n)) return false;
return true;
}
} namespace PollardRho {
const int N = ;
ll q[N]; int qn; inline void PR(ll n) {
if(Millar_Rabin::main(n)) {
q[++qn] = n;
return ;
}
ll a, b, c, del;
while() {
c = rand() % n;
a = b = rand() % n;
b = (mul(b, b, n) + c) % n;
while(a != b) {
del = a-b;
del = gcd(abs(del), n);
if(del > && del < n) {
PR(del); PR(n/del);
return ;
}
a = (mul(a, a, n) + c) % n;
b = (mul(b, b, n) + c) % n;
b = (mul(b, b, n) + c) % n;
}
}
} inline ll getphi(ll n) {
if(n == ) return 1ll;
sort(q+, q+qn+);
ll res = q[] - ;
for (int i=; i<=qn; ++i) {
if(q[i] != q[i-]) res = res * (q[i] - );
else res = res * q[i];
}
return res;
} inline void main(ll n) {
qn = ;
PR(n);
cout << getphi(n) << endl;
}
} int main() {
srand();
ll n; cin >> n;
if(n == ) {
puts("");
return ;
}
PollardRho::main(n);
return ;
}

bzoj4802 欧拉函数(附Millar-Rabin和Pollard-Rho讲解)的更多相关文章

  1. BZOJ4802:欧拉函数(Pollard-Rho,欧拉函数)

    Description 已知N,求phi(N) Input 正整数N.N<=10^18 Output 输出phi(N) Sample Input 8 Sample Output 4 Soluti ...

  2. BZOJ4802 欧拉函数 (Pollard-Rho Miller-Robin)

    题目 求大数的欧拉函数φ\varphiφ 题解 Pollard-Rho 板子 CODE #pragma GCC optimize (3) #include <bits/stdc++.h> ...

  3. [日常摸鱼]bzoj4802 欧拉函数-PollardRho大整数分解算法

    啊居然要特判,卡了好久QAQ (好像Windows下的rand和Linux下的不一样? QwQ一些东西参考了喵铃的这篇blog:http://www.cnblogs.com/meowww/p/6400 ...

  4. BZOJ4802 欧拉函数 数论

    原文链接http://www.cnblogs.com/zhouzhendong/p/8117744.html 题目传送门 - BZOJ4802 题意概括 Description 已知N,求phi(N) ...

  5. 2018.12.17 bzoj4802: 欧拉函数(Pollard-rho)

    传送门 Pollard−rhoPollard-rhoPollard−rho模板题. 题意简述:求ϕ(n),n≤1e18\phi(n),n\le 1e18ϕ(n),n≤1e18 先把nnn用Pollar ...

  6. [BZOJ4802]欧拉函数

    bzoj description 给出\(n\),求\(\varphi(n)\).\(n\le10^{18}\) sol \(Pollard\ Rho\),存个代码. code #include< ...

  7. 【BZOJ4802】欧拉函数(Pollard_rho)

    [BZOJ4802]欧拉函数(Pollard_rho) 题面 BZOJ 题解 这么大的范围肯定不好杜教筛. 考虑欧拉函数的计算式,显然只需要把\(n\)分解就好了. 直接\(Pollard\_rho\ ...

  8. 数学基础IV 欧拉函数 Miller Rabin Pollard's rho 欧拉定理 行列式

    找了一些曾经没提到的算法.这应该是数学基础系最后一篇. 曾经的文章: 数学基础I 莫比乌斯反演I 莫比乌斯反演II 数学基础II 生成函数 数学基础III 博弈论 容斥原理(hidden) 线性基(h ...

  9. BZOJ2186 欧拉函数

    欧拉函数:一般记作φ(n),表示1-n中与n互质的数的数量. 欧拉函数是积性函数,即φ(m*n)=φ(m)*φ(n) //这条定理基友面试时还遇到了= = 欧拉函数的值φ(n)=n*(1-p[1])* ...

随机推荐

  1. mxnet,theano与torch的简单比较

    这篇文章我想来比较一下Theano和mxnet,Torch(Torch基本没用过,所以只能说一些直观的感觉).我主要从以下几个方面来计较它们: 1.学习框架的成本,接口设计等易用性方面. 三个框架的学 ...

  2. 照片 GPS 信息查询

    照片 GPS 信息查询 经纬度查询 https://jingweidu.51240.com/ // 30.27832833333333, 120.01914111111111 30 + 16/60 + ...

  3. 线性代数的本质与几何意义 02. 线性组合、张成的空间、基(3blue1brown 咪博士 图文注解版)

    1. 线性组合 接下来我们要换一个角度来看向量.以二维平面直角坐标系为例,i, j 分别是沿 2 个坐标轴方向的单位向量.那么坐标平面上的其他向量,例如 [ 3  -2 ] [3−与 i, j 是什么 ...

  4. Java微信二次开发(九)

    多媒体文件上传与下载 第一步:找到包com.wtz.vo,新建类WeixinMedia.java package com.wtz.vo; /** * @author wangtianze QQ:864 ...

  5. Lodop打印控件里SET_PRINT_STYLE和SET_PRINT_STYLEA

    LODOP.SET_PRINT_STYLE 对该语句后面的打印项样式设置效果.LODOP.SET_PRINT_STYLEA 针对第一个参数设置的打印项样式设置效果.这两个语句,作用范围不同. 在设置字 ...

  6. HDU4623 CRIME 【状压DP】【同类项合并】

    题目大意: 求相邻元素互质的排列个数. 题目分析: 由于互质只与质因数有关,所以我们对于质因数种类相同的数合并为一类,特殊的,1,17,19,23是一类,因为没有数与他们不互质. 那么我们做各个位进制 ...

  7. NOI 笔试题库(我背不住的部分)

    吐槽 为什么C++选手要会编译Pascall啊!为什么Emacs选手要会使用Vim啊! Linux 中为文件改名使用的命令是:mv 在Linux 中删除当前目录下的test 目录的命令是:rm -r ...

  8. 洛谷 P1879 [USACO06NOV]玉米田 解题报告

    P1879 [USACO06NOV]玉米田Corn Fields 题目描述 农场主\(John\)新买了一块长方形的新牧场,这块牧场被划分成\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ ...

  9. centos7安装redis的正确姿势

    目前redis5已经发布,Redis 5 是 Redis 引入流数据类型(Stream data type)的第一个版本.按照官方的说法,不使用该特性的用户在生产环境中使用 Redis 5 会有更好的 ...

  10. Dijstra算法求最短路径

    参考博客:http://blog.51cto.com/ahalei/1387799        与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下.   ...