题意:定义如果一个数能表示为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*/
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = + ;
const int seed = ;
const int MOD = + ;
const int INF = 0x3f3f3f3f;
int prime[], p[], pn;
ll ans, n;
void get(){
memset(p, , sizeof(p));
pn = ;
for(int i = ; i <= ; i++){
if(!p[i]){
prime[pn++] = i;
for(int j = i * i; j <= ; j += i){
p[j] = ;
}
}
}
}
int main(){
get();
while(~scanf("%lld", &n)){
ans = ;
ll ret;
for(int i = ; i < pn; i++){
ret = pow((double)n, 1.0 / prime[i]);
if(ret == ) break;
ans += ret - ;
}
for(int i = ; i < pn; i++){
for(int j = i + ; j < pn; j++){
ret = pow((double)n, 1.0 / (prime[i] * prime[j]));
if(ret == ) break;
ans -= ret - ;
}
}
for(int i = ; i < pn; i++){
for(int j = i + ; j < pn; j++){
for(int k = j + ; k < pn; k++){
ret = pow((double)n, 1.0 / (prime[i] * prime[j] * prime[k]));
if(ret == ) break;
ans += ret - ;
}
}
}
printf("%lld\n", ans + );
}
return ;
}
/*dfs写法*/
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = + ;
const int seed = ;
const int MOD = + ;
const int INF = 0x3f3f3f3f;
int prime[], p[], pn;
ll ans, n, flag;
void get(){
memset(p, , sizeof(p));
pn = ;
for(int i = ; i <= ; i++){
if(!p[i]){
prime[pn++] = i;
for(int j = i * i; j <= ; j += i){
p[j] = ;
}
}
}
}
void dfs(int start, int p, int times){
if(times == ){
ll ret = pow((double)n, 1.0 / p);
if(ret == ) return;
ret--;
ans += flag * ret;
return;
}
for(int i = start; i < pn; i++){
dfs(i + , p * prime[i], times - );
}
}
int main(){
get();
while(~scanf("%lld", &n)){
ans = ;
ll ret;
flag = -;
for(int i = ; i <= ; i++){
flag *= -;
dfs(, , i);
}
printf("%lld\n", ans + );
}
return ;
}

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. 《Nginx - location配置》

    一:Location 作用 - location 定位 ,也就是可以通过不同URL进行定位,可以很大的增加它配置的灵活性. 二:相关变量 示例: http://192.168.27.27/xxxx $ ...

  2. 使用 SendARP 获取 MAC 地址(使用SendARP API函数,很多相关文章)

    ARP 协议地址解析协议(ARP)是通过解析网路层地址来找寻数据链路层地址的一个在网络协议包中极其重要的网络传输协议.ARP 最初在 1982 年的 RFC 826 中提出并纳入互联网标准 STD 3 ...

  3. Elegant Construction---hdu5813(构造图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5813 题意是:有n个点,每个点都能到达num个点,让我们构造任意一个有向图满足条件,即:使得 i 能到 ...

  4. Linux替换字符串

    sed命令批量替换多个文件中的字符串: 命令:sed -i “s/原字符串/新字符串/g” `grep 原字符串 -rl 所在目录` 例如:我要把 xy 替换为 mn,执行命令: sed -i “s/ ...

  5. golang使用vendor目录来管理依赖包

    Vendor目录介绍 随着Go 1.5 release版本的发布,vendor目录被添加到除了GOPATH和GOROOT之外的依赖目录查找的解决方案.在Go 1.6之前,你需要手动的设置环境变量GO1 ...

  6. spring的统一异常处理

    在控制器(controller)中添加统一异常处理的方法,在方法前面加@ExceptionHandler[(异常类.class)]注解

  7. 页面加载之window.onload=function(){} 和 $(function(){})的区别

    通用的页面加载js有四种方式: 1.window.onload = function(){}; —-js 2.$(window).load(function(){});——Jquery 3.$(doc ...

  8. Andrew Ng-ML-第十章-应用机器学习的建议

    1.如何改进性能不好的学习算法 图1.运用到测试集上效果不佳 当进行一个正则化线性回归时,最小化了代价函数得到参数,但是运用到新的测试集上,发现效果不好,那么如何改进? 1).增加训练集.但是实际上花 ...

  9. GIC400简介

    GIC400是arm公司的中断控制IP,提供axi4接口,主要功能: 1)中断的使能(enable,mask); 中断的优先级(poriority);  中断的触发条件(level-sensitive ...

  10. Geometry

    uva1473 这题说的是 在空间中给了n个点 然后用体积最小的圆锥将这些点包含在内可以在表面上, 将这些点 映射到xoz平面上然后,然后枚举每个上凸包的边和每个点的极值进行判断求得最小的体积 我们会 ...