题意
求1到N范围内能表示为 M^k 的数的数量,k > 1。
思路
设 pi 为质数;
Ai 为具有某性质的数的集合,性质:x∈Ai,x = M^pi [ x = M^ (p1^ t1 * p2 ^ t2 * ... pn ^ tn) = M'^p1 , 当t1 > 1时 ]
ans = |A1 ∪ A2 ... An - 1 ∪ An|
|Ai| = (int) N^(1 / pi)
hint:注意 pow() 精度
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
using namespace std;
typedef long long ll;
const double eps = 1e-8;
int prime[100] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
ll n, ans;
void dfs(int prs, ll q, int cnt)
{
if (cnt == 3)
return;
for (int i = prs + 1; i < 17; i++)
{
ll tmp = prime[i] * q;
if (tmp <= 60)
{
ll p = pow(1.0 * n, 1.0 / tmp);
/**
处理精度
*/
p++;
double t;
while ((t = pow(1.0 * p, 1.0 * tmp)) > n && fabs(n - t) > eps)
p--;
if (p > 1)
{
ans += ((cnt & 1) ? (-1) : 1) * (p - 1);
}
dfs(i, tmp, cnt + 1);
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
while (scanf("%lld", &n) != EOF)
{
ans = 0;
dfs(-1, 1, 0);
cout << ans + 1 << endl;
}
return 0;
}