poj 2478 Farey Sequence 线性筛法优化的欧拉函数
2015-08-10 15:51
405 查看
一:题意:
给定一个数n,求在[1,n]这个范围内两两互质的组合数,该题其实就是求,[2,n]分区间内的所以数组的欧拉函数之和,其中n (2 <= n <= 106)。
二:欧拉函数的概念
1,欧拉函数:
对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,叫做该数的欧拉函数,记作φ(n) 。例如φ(8)=4,因为1,3,5,7均和8互质。
2,欧拉函数计算:
(1) 通式:φ(x)=x * (1-1/p1) * (1-1/p2) * (1-1/p3)…… (1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。
(2) 特例:φ(1)=1。
(3) 注意:每种质因数只一个。比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4
3,欧拉函数的性质:
(1) 若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。因为除了p的倍数外,其他数都跟n互质。
(2) 若m,n互质,φ(mn)=φ(m)φ(n)。
(3) 当n为奇数时,φ(2n)=φ(n).
欧拉打表最重要的两个性质:
(4) 对于质数p,φ(p) = p - 1。 注意φ(1)=1.
(5) 设a为N的质因数,
若(N % a == 0 && (N / a) % a == 0) 则有: E(N)=E(N / a) * a;
若(N % a == 0 && (N / a) % a != 0) 则有:E(N) = E(N / a) * (a - 1)。
这里可以看出p和a都是质数(素数),所以我们可以利用素数的先行筛选法来加快欧拉打表。
三:素数的线性筛选
四:线性欧拉打表代码(poj2478):
给定一个数n,求在[1,n]这个范围内两两互质的组合数,该题其实就是求,[2,n]分区间内的所以数组的欧拉函数之和,其中n (2 <= n <= 106)。
二:欧拉函数的概念
1,欧拉函数:
对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,叫做该数的欧拉函数,记作φ(n) 。例如φ(8)=4,因为1,3,5,7均和8互质。
2,欧拉函数计算:
(1) 通式:φ(x)=x * (1-1/p1) * (1-1/p2) * (1-1/p3)…… (1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。
(2) 特例:φ(1)=1。
(3) 注意:每种质因数只一个。比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4
3,欧拉函数的性质:
(1) 若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1)。因为除了p的倍数外,其他数都跟n互质。
(2) 若m,n互质,φ(mn)=φ(m)φ(n)。
(3) 当n为奇数时,φ(2n)=φ(n).
欧拉打表最重要的两个性质:
(4) 对于质数p,φ(p) = p - 1。 注意φ(1)=1.
(5) 设a为N的质因数,
若(N % a == 0 && (N / a) % a == 0) 则有: E(N)=E(N / a) * a;
若(N % a == 0 && (N / a) % a != 0) 则有:E(N) = E(N / a) * (a - 1)。
这里可以看出p和a都是质数(素数),所以我们可以利用素数的先行筛选法来加快欧拉打表。
三:素数的线性筛选
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; const int Max=100000; bool isPrime[Max+2];// 标记素数 int prime[Max+2];//记录素数 int total=0;//素数个数记录 void Prime() { memset(isPrime,true,sizeof(isPrime)); total=0; for(int i=2; i<=Max; i++) { if(isPrime[i]) prime[total++]=i;//放入表中 for(int j=0; j<total && i*prime[j]<=Max; j++) { isPrime[i*prime[j]]=false;//利用合数必能分解出一个素数 if(i%prime[j]==0) break;//防止重挖 } } printf("%d\n",total); } int main() { Prime(); return 0; }
四:线性欧拉打表代码(poj2478):
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; const int Max=1000010; long long str[Max];//欧拉表 int used[Max];//素数标记 int prime[Max];//素数记录 int N,Size; void print() {//线性打表 memset(used,true,sizeof(used)); Size=0; for(int i=2;i<=1000000;i++) { if(used[i]) { str[i]=i-1;//i是素数的情况 prime[Size++]=i; } for(int j=0;j<Size&& i*prime[j]<1000002;j++) { used[i*prime[j]]=false; if(i%prime[j])//欧拉两个打表定理 str[prime[j]*i]=str[i]*(prime[j]-1); else { str[prime[j]*i]=str[i]*prime[j]; break; } } } for(int i=3;i<=1000000;i++) str[i]=str[i]+str[i-1]; } int main() { print(); while(scanf("%d",&N)!=EOF && N) { printf("%lld\n",str ); } return 0; }
相关文章推荐
- poj 3080 Blue Jeans【字符串处理+ 亮点是:字符串函数的使用】
- CALayer控件(通过操作这个CALayer对象,可以很方便地调整UIView的一些界面属性,比如:阴影、圆角大小、边框宽度和颜色等)
- POJ 2299 Ultra-QuickSort
- UIScreen获取两种类型画面尺寸
- uva 12125 March of the Penguins (最大流)
- 基于FineUI Grid控件添加右键菜单
- hdu-1711 Number Sequence
- HDOJ 5360 Hiking 【priority_queue】
- HDU - 2227 Find the nondecreasing subsequences (树状数组 + 子序列 + 离散化)
- 图片裁剪工具类
- 控件学习---UIButton--摘自培训资料
- POJ3368&&HDOJ1086Frequent values【RMQ】
- request.getHeader("host")
- Func递归Easyui Tree
- poj-2299-Ultra-QuickSort-归并排序求逆序数--或树状数组
- require.js模块化js,r.js压缩js为为一个文件优化请求
- HDU 3732(Ahui Writes Word)多重背包
- UITableView小程序 汽车品牌
- 控件学习---UILabel--摘自培训资料
- shared_ptr/unique_ptr一点体会