【LOJ6235】区间素数个数

【题目链接】

【思路要点】

【代码】


#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;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/81544079
今日推荐