結果
問題 | 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)); }