本题有多组测试数据,每组包含一个整数N,1<=N<=1000000000000000000(10^18).
解析:
如果 A^X<n;那么i^x<n(A>i>=1)必然存在,即有A个数满足条件其x次幂<n
把n作为double型数,对其开k次方(我们不难发现,k<61,对于题目要求的n的最大值开61次方就小于2了)得m,则不大m的正整数的k次方就都是要求的整数。如果我们把k从2到60循环并把(int)m都加起来,这个和是不是就是要求的答案呢?很明显不是,如2的4次方和4的平方都是16、2的6次方和4的平方都等于64,这样以来这个和就可能大于要求的答案了。所以k不能这样循环。我们这样想:既然2的4次方和4的平方都是16、2的6次方和4的平方都等于64,那么我们何不只计4的2次方和4的3次方不计2的4次方和2的6次方呢!即我们只需计一个数的素数次方,这样我们只用把60以内素数计下来进行计算就会去掉了不少的重复。
是不是这样算出的结果t就是答案呢?还不是。这一点就不太好想了,让我费好长时间也找不出反例,还是同学提示才算找到了。比如64(2的2*3次方)既是4的3次方又是8的平方。这一类属于m的k*p次方型(其中k和p为素数),这样以来t的值还比答案大,我们就得去掉这一部分。我们将60以内的素数两两相乘取60以内的积的集合,再对n开方并去掉这部分的重复,这样得到t的就去掉了m的k*p次方型的数重复计算。
看起来没有什么问题了,可是用上面的测试实例一测还是不对。这又是哪里出错了。经过以上种种出错,这次就不难想出原因了。对于m的k*p*g型的数(k、p、g都是素数),它既是(m^k)^(p*g),又是(m^p)^(k*g),同时又是(m^g)^(k*p),这样我们的上一部操作又多去掉了一些值。这里我们把其加上就是了。对于这一类型的数在10^18之内只可能有三个:2的2*3*5次方、2的2*3*7次方以及3的2*3*5次方。如果n包括这几个数,再加上包括的个数算出的t就是最终答案了。
#include<cstdio>
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
typedef __int64 LL;
LL n,a[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
LL res;
void dfs(int s,LL lcm,int bit)
{
LL m;
m=LL(pow(n,1.0/(lcm)));
while(pow(m+1,0.0+lcm)<n) m++;
m--;
if(bit&1) res=res+m;
else res=res-m;
for(int i=s+1;i<17;i++)
{
if(lcm*a[i]<60)
{
dfs(i,lcm*a[i],bit+1);
}
}
}
int main()
{
int i,j,t;
while(~scanf("%I64d",&n))
{
res=0;
for(i=0;i<17;i++)
{
dfs(i,a[i],1);
}
printf("%I64d\n",res+1);
}
return 0;
}