博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 2204 Eddy's 爱好 (容斥原理)
阅读量:4963 次
发布时间:2019-06-12

本文共 1219 字,大约阅读时间需要 4 分钟。

<>

题目大意:

Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣。 

这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1。 
正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题。 
为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。 

解题分析:

解决本题需要先知道一个结论:在一个区间[1,n]中,能被开平方的数一共有 个。同理,在区间[1,n]中,能被开立方的数一共有个.....更一般的,能够被开k次方的数一共会有个数。

因为$k$是幂数,所以$k$在本题的范围很小,考虑枚举$k$。对于$k$,假设$k$是合数,那么k一定能够被分解为若干个质数相乘的形式,而这些质数在前面枚举的时候就会被考虑到,所以我们只需要枚举k为质数的情况。而即使是2作为底数,$2^{60}$就已经大于$10^{18}$,所以我们只需要考虑k为小于60的质数的情况。

k为所有质数的情况中,有一些情况会被重复计算,这个时候就需要用到容斥原理了。因为2*3*5>60,所以我们只需要考虑3个质数相互组合容斥的情况。

#include 
using namespace std;#define rep(i,s,t) for(int i=s;i<=t;i++)typedef long long ll;const int prime[]={ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59 };ll n;inline ll solve(ll k){ //利用结论计算这个区间内能被开(1/k)次方的数的个数(1除外) return pow(n,1.0/k)-1; }int main(){ while(cin>>n){ ll ans1=0,ans2=0,ans3=0; rep(i,0,16)ans1+=solve(prime[i]); rep(i,0,16) rep(j,i+1,16){ ans2+=solve(prime[i]*prime[j]); } rep(i,0,16) rep(j,i+1,16) rep(k,j+1,16){ ans3+=solve(prime[i]*prime[j]*prime[k]); } cout<
<

 

转载于:https://www.cnblogs.com/00isok/p/10692989.html

你可能感兴趣的文章
64位UBUNTU下安装adobe reader后无法启动
查看>>
iTextSharp带中文转换出来的PDF文档显示乱码
查看>>
组件:slot插槽
查看>>
走进C++程序世界------异常处理
查看>>
Nginx配置文件nginx.conf中文详解(转)
查看>>
POJ 1308 Is It A Tree?(并查集)
查看>>
N进制到M进制的转换问题
查看>>
利用sed把一行的文本文件改成每句一行
查看>>
Android应用开发:核心技术解析与最佳实践pdf
查看>>
python——爬虫
查看>>
孤荷凌寒自学python第五十八天成功使用python来连接上远端MongoDb数据库
查看>>
求一个字符串中最长回文子串的长度(承接上一个题目)
查看>>
简单权限管理系统原理浅析
查看>>
springIOC第一个课堂案例的实现
查看>>
求输入成绩的平均分
查看>>
php PDO (转载)
查看>>
wordpress自动截取文章摘要代码
查看>>
[置顶] 一名优秀的程序设计师是如何管理知识的?
查看>>
scanf和gets
查看>>
highcharts 图表实例
查看>>