Description

已知N,求phi(N)

Input

正整数N。N<=10^18

Output

输出phi(N)

Sample Input

8

Sample Output

4

Solution

  • 我们知道 φ(n)=n(1−1p1)(1−1p2)⋅⋅⋅(1−1pk)φ(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})···(1-\frac{1}{p_k})φ(n)=n(1−p1​1​)(1−p2​1​)⋅⋅⋅(1−pk​1​)

  • 其中 n=∏pikin=\prod{p_i^{k_i}}n=∏piki​​ ,pip_ipi​ 为互不相同的质数。

  • 很自然,我们需要将 nnn 分解质因数,但是 n≤1018n\le10^{18}n≤1018 ,很大。

  • 于是我们可以使用 Pollard_rho 算法。

  • 其主要思想是找到两个数 p,qp,qp,q ,使得 n=p∗qn=p*qn=p∗q ,在不断继续分解。

  • 设递归过程 proc(x)proc(x)proc(x) ,若 xxx 是质数(用 Miller_Rabin 算法判断),则 xxx 是 nnn 的一个质因数,并退出过程。

  • 否则找到一个数 yyy ,使 gcd(x,y)>1gcd(x,y)>1gcd(x,y)>1 ,继续递归 proc(y)proc(y)proc(y) 、proc(xy)proc(\frac{x}{y})proc(yx​) 。

  • 那么怎样找到这个数呢?

  • 我们用到了随机化的思想和生日悖论,即找到两个数 x1,x2x1,x2x1,x2 使得 gcd(∣x1−x2∣,x)>1gcd(|x1-x2|,x)>1gcd(∣x1−x2∣,x)>1 ,这样概率就会大得多。

  • 设变换函数 f(x)=(x2+c)%mf(x)=(x^2+c)\%mf(x)=(x2+c)%m ,其中 ccc 是一个随机变量,那么令 x1,x2x1,x2x1,x2 沿着该函数一直走。

  • 可这样走是会成环走回原点的,如下图:

  • 它的形状形似希腊字母 ρρρ ,该算法名即得于此。

  • 判环的话可以用 Floyd 判圈算法:x1=f(x1)x1=f(x1)x1=f(x1)x2=f(f(x2))x2=f(f(x2))x2=f(f(x2))

  • 即 x2x2x2 以两倍速度跑,当 x1=x2x1=x2x1=x2 时重构即可。

  • 可证单 Pollard_rho 算法的期望时间复杂度为 O(n14)O(n^{\frac{1}{4}})O(n41​) 。

  • 然而其中还有一个算法 Miller_Rabin (素数测试算法)还没介绍。

  • 我们当然可以 O(n)O(n)O(n) 线筛出素数,但是在这种时间空间都不允许的情况下,如何快速判定单个素数呢?

  • 根据费马小定理,当 nnn 为素数时,有: an−1≡1(modn)a^{n-1}\equiv1(mod\ n)an−1≡1(mod n)

  • 但是当正整数 nnn 满足 an−1≡1(modn)a^{n-1}\equiv1(mod\ n)an−1≡1(mod n) 时不一定 nnn 就是素数(即逆定理不成立)。

  • 但是我们想如果对于很多个 aaa 都满足上式,是否就能说明 nnn 就是素数了呢?

  • 我们发现这样错误率依然很高,这时二次探测定理就派上用场了。

  • 若一个数 xxx 满足: x2≡1(modp)x^2\equiv1(mod\ p)x2≡1(mod p) ,则合法的解就只有 x=1x=1x=1 或 x=p−1x=p-1x=p−1 。

  • 证明很简单,就是因为 x2−1=(x+1)(x−1)x^2-1=(x+1)(x-1)x2−1=(x+1)(x−1) ,合法解显然。

  • 那么 an−1a^{n-1}an−1 就可以拆成 ad∗2ta^{d*2^t}ad∗2t ,其中 ddd 是奇数。

  • 那么我们先用 ada^dad 检测,之后每次平方,若 (ax)2≡1{(a^x)}^2\equiv1(ax)2≡1 则 ax≡1或p−1(modp)a^x\equiv1或p-1(mod\ p)ax≡1或p−1(mod p) 。

  • 如此一来,检测的成功率就大了不少,更容易检测出是否为质数了。

  • 我们只需随机几个 aaa (或拿几个质数)来判断即可,复杂度约为 log23(n)log_2^3(n)log23​(n)。

  • 至此,我们就成功地实现了算法 Miller_Rabin 和 Pollard_rho 。

Code

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
typedef long long LL;
typedef long double LD;
const int N=65,P=5,prime[P]={2,3,7,61,24251};
LL n,pn;
LL f[N];
inline LL mul(LL a,LL b,LL p)
{a%=p,b%=p;LL c=(LD)a*b/p;c=a*b-c*p;if(c<0) c+=p; elseif(c>p) c-=p;return c;
}
inline LL ksm(LL x,LL y,LL p)
{LL s=1;while(y){if(y&1) s=mul(s,x,p);x=mul(x,x,p);y>>=1;}return s;
}
inline LL twice(LL a,LL p)
{LL d=p-1;int t=0;while(!(d&1)) d>>=1,t++;//p-1=d*2^tLL x,y;x=y=ksm(a,d,p);while(t--){y=mul(x,x,p);if(y==1 && x^1 && x^p-1) return 0;x=y;}return y;
}
inline LL random(LL up)
{return (LL)rand()*rand()%up;
}
LL gcd(LL x,LL y)
{return !y?x:gcd(y,x%y);
}
inline LL abs(LL x,LL y)
{return x<y?y-x:x-y;
}
inline bool Miller_Rabin(LL x)
{for(int i=0;i<P;i++){if(x==prime[i]) return true;if(twice(prime[i],x)^1) return false;}return true;
}
inline LL trans(LL x,LL y,LL z)
{return (mul(x,x,z)+y)%z;
}
void Pollard_rho(LL m)
{if(Miller_Rabin(m)){f[++f[0]]=m;return;}LL x1=0,x2=0,c=0,p=1;while(p==1 || p==m){x1=trans(x1,c,m);x2=trans(trans(x2,c,m),c,m);while(x1==x2){c=random(m);x1=x2=random(m);x2=trans(x2,c,m);}p=gcd(abs(x1-x2),m);}Pollard_rho(p);Pollard_rho(m/p);
}
inline LL getphi(LL m)
{sort(f+1,f+1+f[0]);f[0]=unique(f+1,f+1+f[0])-(f+1);LL sum=m;for(int i=1;i<=f[0];i++)sum=sum/f[i]*(f[i]-1);return sum;
}
int main()
{scanf("%lld",&n);if(n==1) return 0&puts("1");srand(time(NULL));Pollard_rho(n);pn=getphi(n);printf("%lld",pn);return 0;
}

BZOJ 4802: 欧拉函数(大数因数分解算法 Pollard_rho 和素数测试算法 Miller_Rabin)相关推荐

  1. BZOJ - 2186 欧拉函数

    题目的意思大概是求1~N!中和M!互质的数的个数 因为对欧拉函数理解不够深刻所以我是分析得到结果的: 当N<=M的时候显然符合要求的数的个数为0: 当N>M的时候我们要求的是1~N!中不含 ...

  2. bzoj 2818 欧拉函数

    思路:就是对于某个数q,跟他互质的数p,kp和kq的最大公约数是k,那么这个数能组成的答案的数量就是phi[i]乘以某个质数,且乘积小于n 基于这种思路写下这个代码 #include <cstd ...

  3. bzoj 4805: 欧拉函数求和

    Time Limit: 15 Sec  Memory Limit: 256 MB Submit: 539  Solved: 304 [Submit][Status][Discuss] Descript ...

  4. 欧拉函数(Euler_Function)

    一.基本概述 在数论,对正整数n,欧拉函数varphi(n)是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler's totient function.φ函数.欧拉 ...

  5. LightOJ 1370 Bi-shoe and Phi-shoe(欧拉函数)

    题意:题目给出一个欧拉函数值F(X),让我们求>=这个函数值的最小数N,使得F(N) >= F(X); 分析:这个题目有两种做法.第一种,暴力打出欧拉函数表,然后将它调整成有序的,再建立一 ...

  6. poj1284:欧拉函数+原根

    何为原根?由费马小定理可知 如果a于p互质 则有a^(p-1)≡1(mod p)对于任意的a是不是一定要到p-1次幂才会出现上述情况呢?显然不是,当第一次出现a^k≡1(mod p)时, 记为ep(a ...

  7. NOI数学之提高级:欧拉定理和欧拉函数

    欧拉定理详解 欧拉定理详解_郝伟老师的博客--大数据.并行计算与人工智能时代-CSDN博客_欧拉定理 欧拉函数与欧拉定理 欧拉函数与欧拉定理_leader_one的博客-CSDN博客_欧拉定理 欧拉定 ...

  8. UVA 11426 GCD - Extreme (II) (欧拉函数)

    题目传送门:点击打开链接 假设a.b(a<b)互质,那么gcd(a,b)=1,这样当i循环到a.j循环到b时就会向结果中+1,而i循环到2*a.j循环到2*b时就会向结果中+2(gcd(2*a, ...

  9. bzoj 2705: [SDOI2012]Longge的问题(欧拉函数)

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 3077  Solved: 1914 [Submit ...

最新文章

  1. 新东家要哭了,雅虎终于承认上亿用户数据被盗
  2. GoJS超详细入门(插件使用无非:引包、初始化、配参数(json)、引数据(json)四步)...
  3. 转-Multicast server and client in Python
  4. CentOS7中编译安装redis5.0
  5. RSA的JavaScript程序
  6. 地图不显示_图灵搜不显示地图,软件打开一片空白,怎么解决?
  7. 深度学习TF—8.经典CNN模型—LeNet-5、VGG13、AlexNet、GoogLeNet、ResNet、DenseNet
  8. 计算机网络技术提纲,计算机网络技术复习提纲
  9. 数学建模优化模型简单例题_数学建模案例分析--最优化方法建模7习题六 -
  10. Vue 使用 fraola——vue-froala-wysiwyg
  11. linux下查看计划任务,linux查看计划任务.docx
  12. python网络爬虫笔记
  13. 面对这些可能出现的意外,你的运维团队准备好了吗?
  14. 怎么获取淘宝商品详情
  15. 第P9周:YOLOv5-Backbone模块实现
  16. 硬件工程师--医疗器械
  17. 将自己的 ubuntu 系统制作为ISO镜像
  18. 华为OD机试 - 字符串分割
  19. kaggle树叶分类
  20. 企业数据治理,并不止于数据

热门文章

  1. Matlab 基于svm的图像物体分类
  2. 【云炬大学生创业基础笔记】第1章第4节 为什么需要创业讨论
  3. [云炬python3玩转机器学习笔记] 3-12 数据加载和简单的数据探索
  4. 云炬Android开发教程0 jdk下载与安装教程(小白)
  5. OpenGL编程指南5:学习绘制不同风格的曲线
  6. 编译原理之正则表达式
  7. C异常处理机制:setjmp和longjmp
  8. pipe创建匿名管道`
  9. $(@:_config=)的意思
  10. 结构体成员赋值-标记化结构体初始化语法-结构体成员前面加小数点