Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣。
这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1。
正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题。
为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数。
打表+容斥原理
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 using namespace std; 6 typedef long long ll; 7 const int pnum=36; 8 const double eps=1e-8; 9 10 int num[40]={0, 11 2,3,5,6,7, 12 10,11,13,14,15, 13 17,19,21,22,23, 14 26,29,30,31,33, 15 34,35,37,38,39, 16 41,42,43,46,47, 17 51,53,55,57,58, 18 59}; 19 int bit[40]={0, 20 1,1,1,2,1, 21 2,1,1,2,2, 22 1,1,2,2,1, 23 2,1,3,1,2, 24 2,2,1,2,2, 25 1,3,1,2,1, 26 2,1,2,2,2, 27 1}; 28 int high[40]={0, 29 1000000000,1000000,3981,1000,372, 30 63,43,24,19,15, 31 13,8,7,6,6, 32 4,4,3,3,3, 33 3,3,3,2,2, 34 2,2,2,2,2, 35 2,2,2,2,2, 36 2}; 37 38 ll n; 39 40 ll QP(ll a,int i){ 41 ll ans=1,tmp=a; 42 while(i){ 43 if(i&1)ans*=tmp; 44 tmp*=tmp; 45 i>>=1; 46 } 47 return ans; 48 } 49 50 int check(int i){ 51 int l=1,r=high[i]; 52 while(l<=r){ 53 int m=l+((r-l)>>1); 54 ll res=QP(m,num[i]); 55 // printf("%d %d %d %lld\n",l,r,m,res); 56 if(res<=n)l=m+1; 57 else r=m-1; 58 } 59 return r-1; 60 } 61 62 int main(){ 63 // n=9; 64 // printf("%d\n",check(1)); 65 while(scanf("%lld",&n)!=EOF){ 66 ll ans=1; 67 for(int i=1;i<=pnum;++i){ 68 // printf("%d\n",check(i)); 69 if(bit[i]%2)ans+=check(i); 70 else ans-=check(i); 71 } 72 printf("%lld\n",ans); 73 } 74 return 0; 75 }
hdu2204 Eddy's爱好 打表+容斥原理
时间: 2024-10-27 06:16:16