0
点赞
收藏
分享

微信扫一扫

HDU2204 Eddy's爱好


题目链接:​​传送门​​

求小于等于的数中能表示成的数的个数

枚举是不现实的,范围太大,也是根号的级别
所以想一想可不可以枚举
>
所以最大就是
只有是素数时才对答案有贡献
不然会被容斥减掉
因为如果
那么{}
满足的数中,若不是素数
可以等于
为素数
即满足题意的数都可以表示成是素数
所以我们只需累计是素数时对答案的贡献
它对答案的贡献就是,因为
但这样会有些重复,如
这个满足容斥,就是加加减减的那个公式

做法就是预处理出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;
}
}


举报

相关推荐

0 条评论