题目大意:给定一个数字n,求1-n里面所有符合m^k形式的数,k要大于等于2。
思路:如果枚举m的话不现实,m太多。那么就只能枚举k,观察题目数据知道2^60的数据已经足够,所以就是枚举60以内的所有质因子。利用容斥原理来解决。
m^a + m^b -m^(a+b)…
因为一开始排除掉了1,所以最后要加上1。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int prime[100];
double eps = 1e-6;
void init()
{
int len = 0;
for(int i = 2;i<=70;i++)
{
int flag = 1;
for(int j =2;j*j<=i;j++)
{
if(i %j == 0)
{
flag = 0;
break;
}
}
if(flag)
prime[len++] =i;
}
}
int main()
{
ll n;
int len = 0;
init();
while(scanf("%lld", &n) !=EOF)
{
len = 0;
while((1ll<<prime[len+1])<=n) len++;
long long ans = 0;
for(int i = 1;i<(1<<len);i++)
{
int cnt = 0;
ll temp = 1;
for(int j = 0;j<len;j++)
{
if(i &(1<<j))
{
cnt++;
temp *= prime[j];
}
}
if(cnt%2 == 1)
ans +=(long long)(pow(n,1.0/temp)+eps);
else
ans -=(long long)(pow(n,1.0/temp)+eps);
}
printf("%lld\n", ans+1);
}
return 0;
}