結果
問題 | No.3101 Range Eratosthenes Query |
ユーザー |
![]() |
提出日時 | 2025-04-11 22:17:00 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 173 ms / 3,000 ms |
コード長 | 2,671 bytes |
コンパイル時間 | 25,022 ms |
コンパイル使用メモリ | 393,868 KB |
実行使用メモリ | 18,240 KB |
最終ジャッジ日時 | 2025-04-11 22:17:31 |
合計ジャッジ時間 | 18,391 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 24 |
ソースコード
use std::fmt::Write; use bit::BinaryIndexedTree; use proconio::input; fn main() { input! { q: usize, queries: [(usize, usize); q], } const M: usize = 1_000_000; let mut queries = queries .into_iter() .enumerate() .map(|(i, (l, r))| (l, r, i)) .collect::<Vec<_>>(); queries.sort_unstable(); let mut n_divisors = vec![0; M + 1]; let mut bit = BinaryIndexedTree::new(M + 1, 0); for i in 2..=M { if n_divisors[i] == 0 { bit.add(i, 1); } for j in (i..=M).step_by(i) { n_divisors[j] += 1; } } let mut ans = vec![!0; q]; let mut prev_l = 2; for (l, r, i) in queries { if l == 1 { ans[i] = 1; continue; } for i in prev_l..l { for j in (i..=M).step_by(i) { n_divisors[j] -= 1; if n_divisors[j] == 1 { bit.add(j, 1); } } } ans[i] = bit.sum(l, r + 1); prev_l = l; } let mut output = String::new(); for ans in ans { writeln!(&mut output, "{ans}").unwrap(); } println!("{}", output.trim_end()); } #[allow(dead_code)] mod bit { pub struct BinaryIndexedTree<T> { n: usize, array: Vec<T>, e: T, } impl<T> BinaryIndexedTree<T> where T: Clone + std::ops::AddAssign + std::ops::Sub<Output = T> + std::cmp::PartialOrd, { pub fn new(n: usize, e: T) -> Self { Self { n, array: vec![e.clone(); n + 1], e, } } pub fn add(&mut self, i: usize, x: T) { let mut i = i + 1; while i <= self.n { self.array[i] += x.clone(); i += i & i.wrapping_neg(); } } pub fn cum(&self, mut i: usize) -> T { let mut cum = self.e.clone(); while i > 0 { cum += self.array[i].clone(); i -= i & i.wrapping_neg(); } cum } pub fn sum(&self, l: usize, r: usize) -> T { self.cum(r) - self.cum(l) } pub fn lower_bound(&self, mut x: T) -> usize { let mut i = 0; let mut k = 1 << (self.n.next_power_of_two().trailing_zeros()); while k > 0 { if i + k <= self.n && self.array[i + k] < x { x = x - self.array[i + k].clone(); i += k; } k >>= 1; } i } } }