1. 程式人生 > >【LOJ6235】區間素數個數

【LOJ6235】區間素數個數

【題目連結】

【思路要點】

  • 時間複雜度O(N34LogN)

【程式碼】


#include<bits/stdc++.h>

using namespace std;
const int MAXN = 7e6 + 5;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template
<typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9
) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } long long n, limit, m, val[MAXN], ans[MAXN]; int tot, prime[MAXN], Min[MAXN], home1[MAXN], home2[MAXN]; void init(int n) { for (int i = 2; i <= n; i++) { if (Min[i] == 0) { Min[i] = i; prime[++tot] = i; } for
(int j = 1; j <= tot && prime[j] <= Min[i]; j++) { int tmp = prime[j] * i; if (tmp > n) break; Min[tmp] = prime[j]; } } } int main() { read(n), limit = sqrt(n); init(limit); for (long long i = 1, nxt; i <= n; i = nxt) { long long tmp = n / i; nxt = n / tmp + 1; val[++m] = tmp; ans[m] = val[m] - 1; if (tmp <= limit) home1[tmp] = m; else home2[i] = m; } for (int j = 1; j <= tot; j++) for (int i = 1; 1ll * prime[j] * prime[j] <= val[i]; i++) { long long tmp = val[i] / prime[j]; if (tmp <= limit) ans[i] -= ans[home1[tmp]] - (j - 1); else ans[i] -= ans[home2[n / tmp]] - (j - 1); } writeln(ans[1]); return 0; }