欧拉函数详解
2018-06-17 21:19:59来源:未知 阅读 ()
欧拉函数
我们用$\phi(n)$表示欧拉函数
定义:$\phi(n)$表示对于整数$n$,小于等于$n$中与$n$互质的数的个数
性质
1.$\phi(n)$为积性函数
证明:
此处证明需要用到下面计算方法1中的内容,建议先看后面再回过头来看这里
假设存在$p,q$,且$p*q=n$
将$n,p,q$进行质因数分解
$n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$
$p=a_1^{p_1}*a_2^{p_2}...*a_m^{p_m}$
$q=a_{m+1}^{p_{m+1}}*a_{m+2}^{m+2}...*a_k^{p_k}$
那么
$\varphi \left( n\right) =n\prod ^{k}_{i=1}\left( 1-\dfrac {1}{p_{i}}\right)$
$\varphi \left( a\right) =a\prod ^{m}_{i=1}\left( 1-\dfrac {1}{p_{i}}\right)$
$\varphi \left( b\right) =b\prod ^{k}_{i=m+1}\left( 1-\dfrac {1}{p_{i}}\right)$
因为$n=a*b$
显然
$\varphi \left( n\right) =\varphi \left( a\right) \varphi \left( b\right)$
这种方法也是常见的证明一个函数是积性函数的方法
2.$\sum_{d|n}\phi(d)=n$
3.$1$到$n$中与$n$互质的数的和为$n*\dfrac{\phi(n)}{2}(n>1)$
计算方法
$\sqrt(n)$计算单值欧拉函数
假设我们需要计算$\phi(n)$
分情况讨论
1.当$n=1$时
很明显,答案为$1$
2.当$n$为质数时
根据素数的定义,答案为$n-1$
(仅有$n$与$n$不互质)
3.当$n$为合数时
我们已经知道了$n$为素数的情况
不妨对$n$进行质因数分解
设$n=a_1^{p_1}*a_2^{p_2}...*a_k^{p_k}$
假设$k=1$
那么$\phi(p^k)=p^k-p^{k-1}$
证明:
考虑容斥,与一个数互素的数的个数就是这个数减去与它不互素的数的个数
因为$p$是素数,所以在$p^k$中与其不互素的数为$1*p$,$2*p$....$p^{k-1}*p$,有$p^{k-1}$个
得证
当$k\neq 1$时
$$\phi(n)$$
$$=\varphi \left( a^{p_{1}}_{1}a^{p_{2}\ldots }_{2}a^{Pk}_{k}\right)$$
$$=\prod ^{k}_{i=1}a^{P_i}-a^{P_{i}-1}_{i}$$
$$=\prod ^{k}_{i=1}a^{Pi}_{i}(1-\dfrac {1}{p_{i}})$$
$$=n*\prod ^{k}_{i=1}(1-\dfrac {1}{p_{i}})$$
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define LL long long using namespace std; int main() { LL N; while(cin>>N&&N!=0) { int limit=sqrt(N),ans=N; for(int i = 2; i <= limit ; ++i) { if(N%i==0) ans=ans/i*(i-1); while(N%i==0) N=N/i; } if(N>1) ans=ans/N*(N-1); printf("%d\n",ans); } return 0; }
线性筛
因为欧拉函数是积性函数
因此可以使用线性筛法
性质1
若$p$为素数,则$\varphi \left( p\right) =p-1$
证明:
在$1-p$中,只有$(p,p)\neq1$
性质2
若$i\ mod\ p \neq 0$,且$p$为素数
则$\varphi \left( i*p\right) =\varphi \left( i\right) *\varphi \left( p\right)$
$=\varphi \left( i\ast p\right) =\varphi \left( i\right) \ast \left( p-1\right)$
这一步同时利用了性质1和欧拉函数的积性
性质3
若$i\ mod \ p = 0$,且$p$为素数,
则$\varphi \left( i\ast p\right) =\varphi \left( i\right) \ast p$
证明:
没怎么看懂,丢一个链接
http://blog.csdn.net/Lytning/article/details/24432651
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define LL long long using namespace std; const int MAXN=1e6+10; int prime[MAXN],tot=0,vis[MAXN],phi[MAXN],N=10000; void GetPhi() { for(int i=2;i<=N;i++) { if(!vis[i]) { prime[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot&&prime[j]*i<=N;j++) { vis[ i*prime[j] ] = 1; if(i%prime[j]==0) { phi[ i*prime[j] ]=phi[i]*prime[j]; break; } else phi[ i*prime[j] ]=phi[i]*(prime[j]-1); } } } int main() { GetPhi(); cin>>N; printf("%d\n",phi[N]); return 0; }
例题
放几道水题
http://poj.org/problem?id=2407
题解
http://poj.org/problem?id=2478
题解
https://www.luogu.org/problemnew/show/P2158
题解
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- C++ 转换函数搭配友元函数 2020-06-10
- C++ rand函数 2020-06-10
- C++ 友元函数 2020-06-10
- C++ const成员函数 2020-06-03
- C++ 析构函数 2020-06-03
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash