数论知识点3——欧拉函数
2016-07-25 16:26
281 查看
数论知识点3——欧拉函数
1.欧拉函数
指的是不超过n且与n互为素数的正整数的个数,并且如果n是一个素数,欧拉函数的值就等于n - 1,比如对于12来说,1, 5,7,11与它互质,GCD为1,所以φ(12) = 4;通式为φ(x) = x * (1 - 1 / p1) * (1 - 1/p2) * (1 - 1/p3)其中,p为x的素因子,例如对于12来说,素因子是2 3,所以φ(12) = 12* (1/2) * (2/3) = 4,由此可以推出欧拉函数的普通求解法:
int phi(int x) { int ans = x; for(int i = 2; i <= x; ++i) { if(x % i == 0) { ans = ans - ans / i; //φ(x) = x * (1 - 1 / p1) * (1 - 1/p2) * (1 - 1/p3) // 把第一个x放入第一个括号中得 x - x / p1,再把这个结果放入第二个括号 while(x % i == 0) x /= i; } } return ans; }
上面代码有一个致命问题就是超时,时间复杂度是O(n),现在考虑到任何一个合数都有不超过sqrt(n)的素因子,所以这个算法可以写成:
int phi(int x) { int ans = x; for(int i = 2; i * i <= x; ++i) { if(x % i == 0) { ans = ans - ans / i; while(x % i == 0) x /= i; } } if(x > 1) ans = ans - ans / x; return ans; }
[align=left] 这个代码是不是感觉和试除法求因子特别像。看一道题题目吧[/align]
2.POJ 2407
题目意思很简单,就是求给定数字的欧拉函数值,由于数据在1~1000000000之间,所以要用第二份代码,才不会超时。3.欧拉函数打表
就像素数一样,如果我们需要经常判断使用欧拉函数的值,不如提前打一张表,打表的过程和素数筛法非常类似,代码如下:const int maxn = 4000005; LL phi[maxn]; void init() { memset(phi, 0, sizeof(phi)); phi[1] = 1; for(int i = 2; i < maxn; ++i) { if(!phi[i]) { for(int j = i; j < maxn; j += i) { if(!phi[j]) phi[j] = j; phi[j] = phi[j] / i * (i - 1); //phi(n) = n(1 - 1/p1)(1 - 1/p2).... } } } }欧拉函数的打表过程并不是一次phi[j] = phi[j] / i * (i - 1)就可以完成的,我们知道欧拉函数的通式表明一个欧拉函数是由它的素因子构成的,所以打表过程中,首先将所有含有素因子数2的整数,先乘上x * (1 - 1/ 2),然后将所有含有素因子数3的整数,以刚刚的结果或者是原数本身再乘上(1 - 1 / 3),依次循环,所以才说这个和埃式筛法特别的相似。
4.POJ 2478
这道题就是求法雷序列的个数,看题干给的样例,对于每一个序列,如果我们把分母相同的归为一类,就可以看出实际上f(x) = f(x - 1) + φ(x),也就是这道题就是求解欧拉函数的累加和,所以先打表然后累加,然后输出结果即可const int maxn = 1e6 + 5; LL phi[maxn]; LL ans[maxn]; void init() { memset(phi, 0, sizeof(phi)); phi[1] = 1; for(int i = 2; i < maxn; ++i) { if(!phi[i]) { for(int j = i; j < maxn; j += i) { if(!phi[j]) phi[j] = j; phi[j] = phi[j] / i * (i - 1); //phi(n) = n(1 - 1/p1)(1 - 1/p2).... } } } ans[1] = 0; for(int i = 2; i < maxn; ++i) ans[i] = ans[i - 1] + phi[i]; } int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL init(); int num; while(cin >> num && num) { cout << ans[num] << endl; } return 0; }
5.POJ 1284
这道题虽然代码简单,但是用到了一个知识点,就是原根的概念,设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。这道题就是求原根的个数的题目。即为φ(φ(m)),由于m是一个素数,所以φ(m)= m - 1,即最终结果为φ(m - 1).
int phi(int x) { int ans = x; for(int i = 2; i * i <= x; ++i) { if(x % i == 0) { ans = ans - ans / i; while(x % i == 0) x /= i; } } if(x > 1) ans = ans - ans / x; return ans; }
int main()
{
#ifdef LOCAL
///freopen("in.txt", "r", stdin);
///freopen("out.txt", "w", stdout);
#endif // LOCAL
int n;
while(cin >> n)
{
cout << phi(n - 1) << endl;
}
return 0;
}
6.POJ 3090
题意的意思是说现在有一个坐标系,给你一个范围,在这个范围内,从原点出发画一条线段到(x, y)点,假设这条线段不经过其他的点,那么就是成立的,问有多少种情况,表面上是一个几何题目,实际上就是一道简单的数论题目考虑。如果一条线段不能再经过其他的点了,
那么,首先他的终点x,y坐标必须是互质的,不然肯定就可以除以他们的公因子得到一个新的点,假设现在y固定,去找有多少个x和y互质。这不就是欧拉函数吗?然后我们把x固定,同理可得。
其次如果x,y其中一个为0,那么这种情况只有两种也就是(0,1),(1,0)除此之外任何为0的点肯定经过(0,1),(1,0)
最后,如果x == y那么也只有一种情况,也就是(1,1)理由同上。
所以思路就出来了,先打一张欧拉函数表,然后求欧拉函数的累加和的2倍,记得加上3.
static final int maxn = 1005; static final int maxn = 1005; static int[] phi = new int[maxn]; static int[] ans = new int[maxn]; static void init() { phi[1] = 1; for(int i = 2; i < maxn; ++i) { if(phi[i] == 0) { for(int j = i; j < maxn; j += i) { if(phi[j] == 0) { phi[j] = j; } phi[j] = phi[j] / i * (i - 1); } } } ans[0] = 0; ans[1] = 3; for(int i = 2; i < maxn; ++i) { ans[i] = ans[i - 1] + phi[i] * 2; } } public static void main(String[] args) { init(); Scanner cin = new Scanner(System.in); int t; int n; t = cin.nextInt(); for(int i = 1; i <= t; ++i) { n = cin.nextInt(); System.out.println(i + " " + n + " " + ans ); } cin.close(); }其实这些满足条件的点,和法雷序列特别像,我不知道有没有关系,现在法雷序列只用过一次。。。。。
相关文章推荐
- IMS Modify Call (3) accept reject timeout 接受/拒接/超时 视频升级请求
- TCP/IP协议中backlog分析与设置以及TCP状态变化
- 2016最新搭建Struts2开发环境
- 使用C#连接ORACLE数据库
- Eclipse调试(1)——基础篇
- Eclipse调试(1)——基础篇
- 使用netfilter实现输出报文的tcp option增加
- ssh无密码登录设置错误
- 自定义view
- SpringMVC数据的处理
- 让FIREDAC记录数据库的异常日志
- Java类中中文问题
- strip和stripe
- HBuilder底部选项卡的子页面切换效果
- ios 利用 NSURLSession下载图片
- 数据结构--------------AVLTree
- vc连接mysql
- 大数据时代的技术hive:hive介绍
- 构建高性能ASP.NET应用的12点建议
- Android图片压缩(质量压缩和尺寸压缩)