結果
| 問題 |
No.1661 Sum is Prime (Hard Version)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-07-10 19:19:49 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 97 ms / 3,000 ms |
| コード長 | 2,757 bytes |
| コンパイル時間 | 15,762 ms |
| コンパイル使用メモリ | 387,448 KB |
| 実行使用メモリ | 7,324 KB |
| 最終ジャッジ日時 | 2025-03-31 19:36:02 |
| 合計ジャッジ時間 | 18,058 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 22 |
ソースコード
#[allow(unused_imports)]
use std::io::{stdout, BufWriter, Write};
use std::io;
#[allow(dead_code)]
fn read<T: std::str::FromStr>() -> T {
let mut n = String::new();
io::stdin().read_line(&mut n).unwrap();
n.trim().parse().ok().unwrap()
}
#[allow(dead_code)]
fn read_vec<T: std::str::FromStr>() -> Vec<T> {
let mut n = String::new();
io::stdin().read_line(&mut n).unwrap();
n.trim()
.split_whitespace()
.map(|e| e.parse().ok().unwrap())
.collect()
}
fn prime_pi_fast(n: usize) -> usize {
if n <= 3 {
return n.saturating_sub(1);
}
let v = floor_sqrt(n);
let mut smalls: Vec<_> = (0..=v).map(|i| (i + 1) / 2).collect();
let mut s = (v + 1) / 2;
let mut roughs: Vec<_> = (0..s).map(|i| 2 * i + 1).collect();
let mut larges: Vec<_> =
(0..s).map(|i| (n / (2 * i + 1) + 1) / 2).collect();
let mut skip = vec![false; v + 1];
let mut pc = 0;
for p in (3..=v).step_by(2) {
if skip[p] { continue; }
let q = p * p;
pc += 1;
if q * q > n { break; }
skip[p] = true;
for i in (q..=v).step_by(2 * p) {
skip[i] = true;
}
let mut ns = 0;
for k in 0..s {
let i = roughs[k];
if skip[i] { continue; }
let d = i * p;
let x = if d <= v {
larges[smalls[d] - pc]
} else {
smalls[n / d]
};
larges[ns] = larges[k] + pc - x;
roughs[ns] = i;
ns += 1;
}
s = ns;
let mut i = v;
for j in (p..=v / p).rev() {
let c = smalls[j] - pc;
let e = j * p;
while i >= e {
smalls[i] -= c;
i -= 1;
}
}
}
let roughs = roughs;
let pc = pc;
let mut res: usize = larges[0] + (s + 2 * (pc - 1)) * (s - 1) / 2
- larges[1..s].iter().sum::<usize>();
for l in 1..s {
let q = roughs[l];
let m = n / q;
let e = smalls[m / q] - pc;
if e <= l { break; }
let t: usize = roughs[l + 1..=e].iter().map(|&r| smalls[m / r]).sum();
res += t - (e - l) * (pc + l - 1);
}
res
}
fn floor_sqrt(n: usize) -> usize {
if n <= 1 {
return n;
}
let mut lo = 1;
let mut hi = n;
while hi - lo > 1 {
let mid = lo + (hi - lo) / 2;
match mid.overflowing_mul(mid) {
(x, false) if x <= n => lo = mid,
_ => hi = mid,
}
}
lo
}
fn main() {
let v = read_vec::<usize>();
let l = v[0];
let r = v[1];
println!("{}", prime_pi_fast(r) - prime_pi_fast(l - 1) + prime_pi_fast(2 * r) - prime_pi_fast(2 * l));
}