fork download
  1. // Tổng độ dài của các truy vấn khôgn vượt quá 10^6
  2.  
  3. // tổng các (R(i) - L(i) + 1) không vượt quá 10^6
  4. // => R(i) - L(i) + 1 không vượt quá 10^6
  5.  
  6. // nên tuy L(i), R(i) tối đa 10^9, nhưng độ dài đoạn lại đủ nhỏ.
  7. // => Sàng trên đoạn
  8.  
  9. // Ý tưởng thì vẫn là dựa vào sàng bình thường [2, N]
  10.  
  11. // Nhưng thay vì mình cứ mặc định for bội từ i * i, mình có thể for từ thằng bội đầu tiên của i mà >= L
  12.  
  13. // bội đầu tiên của i mà >= L có công thức: ([L / i] làm tròn lên) * i
  14. // (L / i) làm tròn lên = (L + i - 1) / i làm tròn xuống
  15. // => ((L + i - 1) / i) * i
  16.  
  17. // => j = max(i * i, (L + i - 1) / i * i)
  18.  
  19. #include <bits/stdc++.h>
  20. using namespace std;
  21.  
  22. #define fst first
  23. #define snd second
  24.  
  25. typedef long long ll;
  26. typedef pair<int, int> ii;
  27.  
  28. const ll LINF = (ll)1e18;
  29. const int INF = (int)1e9;
  30.  
  31. const int N = (int)1e6 + 5;
  32. // i: L -> R
  33. // -> i - L
  34. // [0 -> R - L]
  35.  
  36. bool isPrime[N];
  37.  
  38. int main() {
  39. ios::sync_with_stdio(0);
  40. cin.tie(0);
  41. int T; cin >> T;
  42.  
  43. // j = i * i
  44. // j = ((L + i - 1) / i) * i
  45. // => j = max(..., ...)
  46.  
  47. while (T--) {
  48. int L, R;
  49. cin >> L >> R;
  50.  
  51. L = max(L, 2); // trường hợp đặc biệt L = 1 sẽ dẫn đến sai lỗi đáng tiếc
  52. // vì thường mình for từ 2 nên hay bị bỏ qua thèn 1 mà thèn 1 nó ko nguyên tố
  53. // nên mặc định L >= 2 cho chắc cú
  54. for (int i = 0; i <= R - L; i++) isPrime[i] = true;
  55.  
  56. for (int i = 2; i * i <= R; i++) {
  57. for (int j = max(i * i, (L + i - 1) / i * i); j <= R; j += i) isPrime[j - L] = false;
  58. }
  59.  
  60. int cnt_prime = 0;
  61. for (int i = 0; i <= R - L; i++) cnt_prime += (isPrime[i]);
  62.  
  63. cout << cnt_prime << '\n';
  64. }
  65. }
  66.  
Success #stdin #stdout 0.01s 5292KB
stdin
Standard input is empty
stdout
Standard output is empty