分析:对于这个题,我们首先要知道是基于以下的事实来计算的:
对于一个数n,从1~n中假设有x个数是满足p^k形式的,这里的k最多到62,那么对于每一个k,我们需要找到这个数x满足x^k最
接近n,那么现在的问题就是对于每一个k找出对应的x,那么这个怎么找呢?
我们可以这样考虑,由于是找最接近的,我们可以先大致确定一个数r,那么可以通过r=pow(n,1/k)来计算,然后我们分别计
算(r-1)^k,r^k,(r+1)^k,然后看这三个数哪个最接近n就行了,这里要注意(r+1)^k计算时可能会超过LL,所以有一些处理。
然后就是相当于容斥的部分了。
#include#include #include #include using namespace std; typedef long long LL; const LL INF=1e18+300; const LL T=(LL)1<<31; LL num[105]; LL multi(LL a,LL b) { LL ans=1; while(b) { if(b&1) { double judge=1.0*INF/ans; if(a> judge) return -1; ans*=a; } b>>=1; if(a>T&&b>0) return -1; a=a*a; } return ans; } LL find(LL x,LL k) { LL r=(LL)pow(x,1.0/k); LL t,p; p=multi(r,k); if(p==x) return r; if(p>x||p==-1) r--; else { t=multi(r+1,k); if(t!=-1&&t<=x) r++; } return r; } LL Solve(LL n) { int i,k=0; memset(num,0,sizeof(num)); if(n<=3) return n; num[1]=n; for(i=2;i<63;i++) { num[i]=find(n,i)-1; if(!num[i]) break; } k=i; for(int i=k-1;i>0;i--) for(int j=1;j>m>>n) { if(m==0&&n==0) break; cout<