hdu2204Eddy's爱好
2024-09-03 06:05:54
大概题意是要你输出1到n中,可以表示成a^b的数,a,b都是大于0的整数的个数,
当中b大于1。
由于1到n中。可以全然开平方的个数就是(n^0.5)的整数部分。
以此类推能够得到,全然开立方。全然开四次方各种的次数。
这种话,要枚举的数量太大。有什么办法能够让枚举的数量降低呢?
有的,因为随意一个大于1的整数都能够表示成两个素数的乘积。
于是。可以全然开平方的个数包含了可以全然开四次方,
八次方。十六次方以此类推的个数。
于是,可以知道,仅仅须要枚举可以全然开素数次方的个数就可以。
又由于n最大不会超过10^18,由于64位整型号可以表示的最大数
大概就是9*10^18多,所以不须要特地写个大数。
又由于这样。所以素数仅仅须要枚举到大小不超过63就可以。由于
2^63-1就是64位整型的最大值。所以这个n最大,开个63次方的整数部分
结果肯定为1,为1的话就代表可以1到n中可以全然开这个次方
的数仅仅有1个,又由于1可以开随意次方,所以,这个数肯定是1啦,
于是超过63的素数不是必需枚举了,由于仅仅有1可以开这么多次方。
对于一个数n,从小到大枚举到使n开次方为1就可以,再把前面
全部开次方的结果都累加,再除去之中反复的部分。终于结果就是
题意所要求的个数。
反复的部分是说,可以全然开六次方的肯定也可以全然开二次方和三次方,
这个能全然开六次方的个数被反复加了一次。所以要减去一次,
以此类推把全部反复的部分除去就可以。
另一点,这个题目,有的人用long long读入n的时候,会wa,
这个的话,是各种编译器的原因,用cin读入就好了,
至于有的人说缺失精度什么的。仅仅是想多了。
我的代码例如以下:
#include<iostream>
#include<cmath>
using namespace std;
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};
void result(long long x)
{
int i,j,k;
long long tmp,ans=1;
for(i=0;;i++)
{
tmp=(long long)(pow(x,1.0/prime[i]));
if(tmp<2)
break;
ans+=tmp-1;
for(j=i+1;;j++)
{
tmp=(long long)(pow(x,1.0/(prime[i]*prime[j])));
if(tmp<2)
break;
ans-=tmp-1;
for(k=j+1;;k++)
{
tmp=(long long)(pow(x,1.0/(prime[i]*prime[j]*prime[k])));
if(tmp<2)
break;
ans+=tmp-1;
}
}
}
printf("%lld\n",ans);
}
int main()
{
long long x;
while(cin>>x)
result(x);
}
最新文章
- shell脚本重新挂载出问题的卷
- 安卓手机APP压力monkey测试
- [LintCode] Create Maximum Number 创建最大数
- mongodb driver c#语法
- LRU算法实现
- 改变Oracle数据库连接端口
- HW6.25
- oracle rac 学习(转载)
- TCP/IP笔记
- 014_IP专项研究监控
- Linux安装/升级pip
- nginx请求数据超长的问题解决
- SCP和Rsync远程拷贝的几个技巧
- Guava之ImmutableMap使用示例
- Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
- asp.net菜鸟到中级程序员的飞跃 --30本好书点评
- Educational Codeforces Round 28
- linux下mysql的安装配置
- cf1088D. Ehab and another another xor problem(思维)
- 20155319 《Java程序设计》实验一(Java开发环境的熟悉)实验报告