[HDOJ4135]Co-prime
2015-08-17 15:08
357 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4135
题意:给一个区间[a,b],再给你一个数n,求在这个区间[a,b]中与n互质的数的个数。
思路:这是一道数学题,如果数据范围不大的话可以直接套用欧拉函数,但是数据范围给得很大。所以用容斥原理来做。
具体思路就是计算[1,a]中与n非互质的数的个数以及[1,b]中与n非互质的数的个数,然后用上限减掉非互质的数的个数,之后作差即可。首先分解n的质因数,接着用一个变量的二进制表示质因数中1的数量,当这个变量是偶数的时候就加,奇数的话就减,因为重复计算了(详解见书《挑战程序设计竞赛P297》)。代码如下:
题意:给一个区间[a,b],再给你一个数n,求在这个区间[a,b]中与n互质的数的个数。
思路:这是一道数学题,如果数据范围不大的话可以直接套用欧拉函数,但是数据范围给得很大。所以用容斥原理来做。
具体思路就是计算[1,a]中与n非互质的数的个数以及[1,b]中与n非互质的数的个数,然后用上限减掉非互质的数的个数,之后作差即可。首先分解n的质因数,接着用一个变量的二进制表示质因数中1的数量,当这个变量是偶数的时候就加,奇数的话就减,因为重复计算了(详解见书《挑战程序设计竞赛P297》)。代码如下:
#include <iostream> #include <cstdio> #include <vector> #include <cmath> using namespace std; typedef long long LL; vector<LL> v; LL a, b; LL n; void init() { v.clear(); scanf("%I64d %I64d %I64d", &a, &b, &n); LL nn = (LL)sqrt(n) + 1; for(int i = 2; i < nn; i++) { if(n % i == 0) { v.push_back(i); while(n % i == 0) { n /= i; } } } if(n > 1) { v.push_back(n); } } LL solve(LL x, LL y) { LL ans; LL m ,cnt; LL s = 1 << v.size(); for(int i = 1; i < s; i++) { m = 1; cnt = 0; for(int j = 0; j < v.size(); j++) { if(i & (1 << j)) { m *= v[j]; cnt++; } } if(cnt & 1) { ans += x / m; } else { ans -= x / m; } } return x - ans; } int main() { int t; int kase = 1; scanf("%d", &t); while(t--) { init(); LL l, r; l = solve(a-1, n); r = solve(b, n); cout << "Case #" << kase++ << ": " << r - l << endl; } }
相关文章推荐
- <meta-data>读取方法
- CocoStudio:ImageView分析
- [网狐]6603后台最高管理员密码修改
- UIWebView与js交互(一)
- androidのstring.xml转译、特殊字符问题处理
- 深入解析Oracle学习笔记(第七章)
- c 语言实现httpclient端的post,get, delete
- Mysql事务隔离级别学习
- Google测试分享-测试经理
- idea新建项目完整过程
- X64 Win7(win2008)连接SqlServer2005慢的解决办法
- sqoop基本 操作
- 30多个iOS常用动画,带详细注释
- bootstrap单击导航条下的li后,自动收回
- ZOJ 3818 Pretty Poem (2014年牡丹江赛区网络赛J题)
- Linux环境Nginx安装与调试以及PHP安装
- IOS UItableView得到group如何摆脱的剪裁线条样式问题
- AFNnetworking详解
- windows遍历文件夹
- eclipse构建maven的web项目