题意:定义如果一个数能表示为M^k,那么这个数是好数,问你1~n有几个好数。

思路:如果k是合数,显然会有重复,比如a^(b*c) == (a^b)^c,那么我们打个素数表,指数只枚举素数,2^60 > 1e18,所以打60以内素数就够了。但是显然指数为素数依然会有重复的,比如(a^b)^c == (a^c)^b,这里就要用到容斥了。我们如果用一个数组a[i]表示指数为第i个素数的数的个数,那么最终答案应该是,加上一个的,减去两个的,加上三个的(因为2 * 3 * 5 * 7 > 60,最多只能有三个相乘形成指数)。如果我要算出指数为p的这样的数有几个,那么可以计算pow(n,1.0/p)。先写了一个朴素版的,纯枚举;后来又写了一个dfs的,这样大于3也能用了。

讲一些小细节,每次算出个数我们都减去1这里是去掉了1^p,我们在最后答案加上1。最后一个样例答案是“1001003332”,我的“1001003331”但是过了。

容斥:对于几个集合求解并集大小,那么采用一种方法:加上所有单个集合,减去所有两个集合相并部分,加上所有三个集合相并部分,减去所有四个集合相并部分.....

参考:学习容斥原理

代码:

  1. /*朴素写法1*/
  2. #include<set>
  3. #include<map>
  4. #include<cmath>
  5. #include<queue>
  6. #include<cstdio>
  7. #include<cstring>
  8. #include<iostream>
  9. #include<algorithm>
  10. #define ll long long
  11. using namespace std;
  12. const int maxn = + ;
  13. const int seed = ;
  14. const int MOD = + ;
  15. const int INF = 0x3f3f3f3f;
  16. int prime[], p[], pn;
  17. ll ans, n;
  18. void get(){
  19. memset(p, , sizeof(p));
  20. pn = ;
  21. for(int i = ; i <= ; i++){
  22. if(!p[i]){
  23. prime[pn++] = i;
  24. for(int j = i * i; j <= ; j += i){
  25. p[j] = ;
  26. }
  27. }
  28. }
  29. }
  30. int main(){
  31. get();
  32. while(~scanf("%lld", &n)){
  33. ans = ;
  34. ll ret;
  35. for(int i = ; i < pn; i++){
  36. ret = pow((double)n, 1.0 / prime[i]);
  37. if(ret == ) break;
  38. ans += ret - ;
  39. }
  40. for(int i = ; i < pn; i++){
  41. for(int j = i + ; j < pn; j++){
  42. ret = pow((double)n, 1.0 / (prime[i] * prime[j]));
  43. if(ret == ) break;
  44. ans -= ret - ;
  45. }
  46. }
  47. for(int i = ; i < pn; i++){
  48. for(int j = i + ; j < pn; j++){
  49. for(int k = j + ; k < pn; k++){
  50. ret = pow((double)n, 1.0 / (prime[i] * prime[j] * prime[k]));
  51. if(ret == ) break;
  52. ans += ret - ;
  53. }
  54. }
  55. }
  56. printf("%lld\n", ans + );
  57. }
  58. return ;
  59. }
  1. /*dfs写法*/
  2. #include<set>
  3. #include<map>
  4. #include<cmath>
  5. #include<queue>
  6. #include<cstdio>
  7. #include<cstring>
  8. #include<iostream>
  9. #include<algorithm>
  10. #define ll long long
  11. using namespace std;
  12. const int maxn = + ;
  13. const int seed = ;
  14. const int MOD = + ;
  15. const int INF = 0x3f3f3f3f;
  16. int prime[], p[], pn;
  17. ll ans, n, flag;
  18. void get(){
  19. memset(p, , sizeof(p));
  20. pn = ;
  21. for(int i = ; i <= ; i++){
  22. if(!p[i]){
  23. prime[pn++] = i;
  24. for(int j = i * i; j <= ; j += i){
  25. p[j] = ;
  26. }
  27. }
  28. }
  29. }
  30. void dfs(int start, int p, int times){
  31. if(times == ){
  32. ll ret = pow((double)n, 1.0 / p);
  33. if(ret == ) return;
  34. ret--;
  35. ans += flag * ret;
  36. return;
  37. }
  38. for(int i = start; i < pn; i++){
  39. dfs(i + , p * prime[i], times - );
  40. }
  41. }
  42. int main(){
  43. get();
  44. while(~scanf("%lld", &n)){
  45. ans = ;
  46. ll ret;
  47. flag = -;
  48. for(int i = ; i <= ; i++){
  49. flag *= -;
  50. dfs(, , i);
  51. }
  52. printf("%lld\n", ans + );
  53. }
  54. return ;
  55. }

HDU 2204 Eddy's爱好(容斥原理dfs写法)题解的更多相关文章

  1. HDU 2204 Eddy's 爱好 (容斥原理)

    <题目链接> 题目大意: Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣. 这些特殊数是 ...

  2. hdu 2204 Eddy's爱好 容斥原理

    Eddy's爱好 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem ...

  3. HDU 2204 Eddy's爱好(容斥原理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2204 解题报告:输入一个n让你求出[1,n]范围内有多少个数可以表示成形如m^k的样子. 不详细说了, ...

  4. hdu 2204 Eddy's爱好

    // 一个整数N,1<=N<=1000000000000000000(10^18).// 输出在在1到N之间形式如M^K的数的总数// 容斥原理// 枚举k=集合{2,3,5,7,11,1 ...

  5. HDU - 2204 Eddy's爱好 (数论+容斥)

    题意:求\(1 - N(1\le N \le 1e18)\)中,能表示成\(M^k(M>0,k>1)\)的数的个数 分析:正整数p可以表示成\(p = m^k = m^{r*k'}\)的形 ...

  6. Eddy's爱好(dfs+容斥)

    Eddy's爱好 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  7. hdoj 2204 Eddy's爱好

    原文链接:http://www.cnblogs.com/DrunBee/archive/2012/09/05/2672546.html 题意:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K ...

  8. HDU 2204Eddy's爱好(容斥原理)

    Eddy's爱好 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  9. hdu2204 Eddy's爱好 打表+容斥原理

    Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣.这些特殊数是这样的:这些数都能表示成M^K,M和K是 ...

随机推荐

  1. atitit. orm框架的hibernate 使用SQLQuery createSQLQuery addEntity

    atitit. orm框架的hibernate 使用SQLQuery createSQLQuery addEntity 1. addEntity 对原生SQL查询运行的控制是通过SQLQuery接口进 ...

  2. 第二课 eclipse安装

    下载并解压到C:\Program Files\eclipse 目录情况如图所示:

  3. SSH进行登录远程主机,实验室网站,项目

    1:下载putty,双击putty.exe     http://www.putty.be/latest.html 输入要连接的ip和端口号,直接打开open.或者在saved Sessions框里面 ...

  4. ID和Name

    ID和Name都可以用来标识一个标记,Javascript分别有两个方法getElementById和getElementByName来定位Dom节点. 区别如下: 1.我们知道在网页做Post提交时 ...

  5. c#实现图片二值化例子(黑白效果)

    C#将图片2值化示例代码,原图及二值化后的图片如下: 原图: 二值化后的图像: 实现代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  6. python中的re模块中的向后引用和零宽断言

    1.后向引用 pattern = re.compile(r"(\w+)")#['hello', 'go', 'go', 'hello'] # pattern = re.compil ...

  7. Selenium Webdriver——操作隐藏的元素(二)display属性

    有时候我们会碰到一些元素不可见,这个时候selenium就无法对这些元素进行操作了.例如,下面的情况: 页面主要通过“display:none”来控制整个下拉框不可见.这个时候如果直接操作这个下拉框, ...

  8. git的使用(包括创建远程仓库到上传代码到git的详细步骤以及git的一些常用命令)

    A创建远程仓库到上传代码到git 1)登陆或这注册git账号 https://github.com 2)创建远程仓库 3)打开终端输入命令 cd到你的本地项目根目录下,执行如下git命令 git in ...

  9. 54. Spiral Matrix(剑指offer--19)

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  10. linux安装composer及安装yii2

    wget https://getcomposer.org/download/1.3.2/composer.phar mv composer.phar /usr/local/bin/composer c ...