题目链接:传送门
求小于等于的数中能表示成
的数的个数
枚举和
是不现实的,范围太大,
也是根号的级别
所以想一想可不可以枚举>
所以最大就是
只有是素数时才对答案有贡献
不然会被容斥减掉
因为如果
那么{}
满足的数中,若
不是素数
则可以等于
且
为素数
即满足题意的数都可以表示成,
是素数
所以我们只需累计是素数时对答案的贡献
它对答案的贡献就是,因为
但这样会有些重复,如和
这个满足容斥,就是加加减减的那个公式
做法就是预处理出60以内的素数再算贡献再容斥
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define
#define
using namespace std;
typedef long long ll;
ll pri[17] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
ll n;
ll calc(ll a) {
return pow(n, 1.0 / a) - 1;
}
int main(int argc, char const *argv[]) {
while (cin >> n) {
ll c1 = 0, c2 = 0, c3 = 0;
for (int i = 0; i < 17; i++) c1 += calc(pri[i]);
for (int i = 0; i < 17; i++)
for (int j = i + 1; j < 17; j++)
c2 += calc(pri[i] * pri[j]);
for (int i = 0; i < 17; i++)
for (int j = i + 1; j < 17; j++)
for (int k = j + 1; k < 17; k++)
c3 += calc(pri[i] * pri[j] * pri[k]);
cout << c1 - c2 + c3 + 1 << endl;
}
}