传送门: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. 关于python项目路径导入自己写的库出错的一点思考

    其实也是在写自己项目的时候遇到的,以前也遇到了但是一直采取的是回避的策略,这次总算弄清楚所以总结一下. 这个项目的顶级目录是medivac,他本身是一个python模块. 熟悉flask的人都知道,在 ...

  2. Python——信号量

    信号量 某一段代码,同一时间,只能被N个进程使用 import time import random from multiprocessing import Porcess from multipro ...

  3. JavaScript——变量

    本文简述了JavaScript变量的数据类型,以及变量类型检测与类型转换 一.介绍 JavaScript的变量有6种数据类型,包含5种原始类型和1种对象类型.本人比较喜欢用逻辑图的形式总结知识点,这样 ...

  4. BZOJ4891 TJOI2017龙舟(Polllard-Rho)

    对给定模数分解质因数后约分即可.依然常数巨大过不了. #include<iostream> #include<cstdio> #include<cmath> #in ...

  5. python构建bp神经网络_鸢尾花分类(一个隐藏层)__1.数据集

    IDE:jupyter 目前我知道的数据集来源有两个,一个是csv数据集文件另一个是从sklearn.datasets导入 1.1 csv格式的数据集(下载地址已上传到博客园----数据集.rar) ...

  6. android viewflipper的使用 实现图片滑动效果

    package com.homer.viewflipper; import android.app.Activity; import android.os.Bundle; import android ...

  7. 【BZOJ2299】[HAOI2011]向量(数论)

    [BZOJ2299][HAOI2011]向量(数论) 题面 BZOJ 洛谷 题解 首先如果我们的向量的系数假装可以是负数,那么不难发现真正有用的向量只有\(4\)个,我们把它列出来.\((a,b)(a ...

  8. 洛谷 P2057 [SHOI2007]善意的投票 解题报告

    P2057 [SHOI2007]善意的投票 题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人都有自己的主见,但是为了照 ...

  9. Linux磁盘和文件系统简介

    Linux磁盘和文件系统简介 1.文件系统:存储设备上存储数据的方式方法 磁盘主要由盘片.机械手臂.磁头和主轴马达组成,而数据的写入实际是写在盘片上,磁盘的最小存储单位为扇区,每个扇区为512字节,扇 ...

  10. ZABBIX 3.4 监控服务器TCP连接状态(六)

    TCP的连接状态对于我们web服务器来说是至关重要的,尤其是并发量ESTAB:或者是syn_recv值,假如这个值比较大的话我们可以认为是不是受到了攻击,或是是time_wait值比较高的话,我们要考 ...