数论之欧拉函数
2015-11-06 22:51
316 查看
定义:欧拉函数φ(n),表示小于或等于n的数中与n互质的数的数目。
性质:
1) φ(1) = 1
2) 若n是质数p的k次幂,φ(n) = p^k - p^(k-1) = (p - 1)*p^(k - 1)
因为p为质数,所以与n不互质的数只有p的倍数,一共有p^(k-1)个,由此可得。
3) 若m, n互质,φ(m*n) = φ(m) * φ(n)
求法:
1、对任意一个正整数n,pi为其第 i 个质因子,一共 j 个:
φ(n) = (p1 - 1)*p1^(k1 - 1) * … * (pj - 1)*pj^(kj - 1)
= n * (1 - 1/p1) * … * (1 - 1/pj)
可以根据这条式子,我们可以使用类似素数筛法的方式来求解:
2、上面那种方法似乎慢了一点,根据欧拉函数的性质,我们可以有如下递推式:
p 为 n 最小质因数,根据上面性质2)、3),我们可以得到下面两条递推公式:
(1) n % (p^2) == 0 , φ(n) = φ(n/p) * p ;
此时n/p与p存在公因子p,根据性质2),因为φ(n/p)中必然已经计算过p-1了,那么每多一维p,φ(p)需要乘上p。
(2) n % (p^2) != 0 , φ(n) = φ(n/p) * (p-1) ;
此时n/p与p互质,所以根据性质3),并且φ(p)=p-1,可以得到。
这使得我们需要先求出n的最小质因数:
时间复杂度为O( log(n) * n )
欧拉函数的重要性质:
1、如果n为正整数且a是一个与n互质的数,那么:
a ^ φ(n) ≡ 1 (mod n)
这个性质称为欧拉定理,其实是费马小定理的一个升级版。
2、当模m有原根时,有φ(φ(m))个原根。
性质:
1) φ(1) = 1
2) 若n是质数p的k次幂,φ(n) = p^k - p^(k-1) = (p - 1)*p^(k - 1)
因为p为质数,所以与n不互质的数只有p的倍数,一共有p^(k-1)个,由此可得。
3) 若m, n互质,φ(m*n) = φ(m) * φ(n)
求法:
1、对任意一个正整数n,pi为其第 i 个质因子,一共 j 个:
φ(n) = (p1 - 1)*p1^(k1 - 1) * … * (pj - 1)*pj^(kj - 1)
= n * (1 - 1/p1) * … * (1 - 1/pj)
可以根据这条式子,我们可以使用类似素数筛法的方式来求解:
int phi[MAXN]; void getPhi(int n) { for(int i=1;i<n;i++) //初始化为自身 phi[i]=i; for(int i=2;i<n;i++) if(phi[i]==i) { phi[i]=i-1; for(int j=i*2;j<n;j+=i) phi[j]=phi[j]/i*(i-1); } }
2、上面那种方法似乎慢了一点,根据欧拉函数的性质,我们可以有如下递推式:
p 为 n 最小质因数,根据上面性质2)、3),我们可以得到下面两条递推公式:
(1) n % (p^2) == 0 , φ(n) = φ(n/p) * p ;
此时n/p与p存在公因子p,根据性质2),因为φ(n/p)中必然已经计算过p-1了,那么每多一维p,φ(p)需要乘上p。
(2) n % (p^2) != 0 , φ(n) = φ(n/p) * (p-1) ;
此时n/p与p互质,所以根据性质3),并且φ(p)=p-1,可以得到。
这使得我们需要先求出n的最小质因数:
int phi[MAXN]; void getPhi(int n) { int minDiv; for(int i=1;i<n;i++) phi[i]=i; for(int i=2;i*i<n;i++) //最小质因数 if(phi[i]==i) { for(int j=i*i;j<n;j+=i) phi[j]=i; } phi[1]=1; for(int i=2;i<n;i++) { minDiv=phi[i]; if((i/phi[i])%phi[i]==0) phi[i]=phi[i/phi[i]]*phi[i]; else phi[i]=phi[i/phi[i]]*(phi[i]-1); } }
时间复杂度为O( log(n) * n )
欧拉函数的重要性质:
1、如果n为正整数且a是一个与n互质的数,那么:
a ^ φ(n) ≡ 1 (mod n)
这个性质称为欧拉定理,其实是费马小定理的一个升级版。
2、当模m有原根时,有φ(φ(m))个原根。
相关文章推荐
- 深入浅出Java三大框架SSH与MVC的设计模式
- LeetCode OJ:Longest Substring Without Repeating Characters(最长无重复字符子串)
- C++常见类型所占字节大小
- haproxy
- 我第二次用SecureCRT时的糗事
- Linux 下 shell 编写 计算器
- Shmget 参数 0600的解释
- effective c++ 考虑写出一个不抛出异常的swap函数
- Python之str方法
- Animator无法添加event
- SpringMVC使用ResponseBody报406错误
- mac下使用自带的vim编辑器编辑文件
- Scrum Meeting 11.06
- Spring 知识总结
- apache配置httpd-vhosts
- Java 引用传递的实验
- cocos2d-x设计模式发掘之九:委托模式
- 设计模式-简单工厂模式(实现,可与前文进行比较)
- 开始swift学习之路
- Ubuntu中Terminal和GNOME文件管理器的互通方法和命令