結果
問題 |
No.1332 Range Nearest Query
|
ユーザー |
|
提出日時 | 2025-02-06 00:55:40 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 924 ms / 2,500 ms |
コード長 | 3,657 bytes |
コンパイル時間 | 15,158 ms |
コンパイル使用メモリ | 400,788 KB |
実行使用メモリ | 94,508 KB |
最終ジャッジ日時 | 2025-02-06 00:56:36 |
合計ジャッジ時間 | 42,118 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 48 |
コンパイルメッセージ
warning: unused variable: `n` --> src/main.rs:111:9 | 111 | let n: usize = lines.next().unwrap().unwrap().trim().parse().unwrap(); | ^ help: if this is intentional, prefix it with an underscore: `_n` | = note: `#[warn(unused_variables)]` on by default warning: variable `L` should have a snake case name --> src/main.rs:87:17 | 87 | let mut L = self.size + l; | ^ help: convert the identifier to snake case: `l` | = note: `#[warn(non_snake_case)]` on by default warning: variable `R` should have a snake case name --> src/main.rs:88:17 | 88 | let mut R = self.size + r; | ^ help: convert the identifier to snake case: `r`
ソースコード
use std::io::{self, BufRead}; const MAX_INT: i64 = i64::MAX; struct SegmentTree { size: usize, array: Vec<Vec<i64>>, } impl SegmentTree { fn new(init_array: &[i64]) -> Self { let mut n = 1; while n < init_array.len() { n *= 2; } let mut array = vec![Vec::new(); 2 * n]; for (i, &a) in init_array.iter().enumerate() { array[n + i].push(a); } let mut tree = SegmentTree { size: n, array }; tree.build(); tree } fn build(&mut self) { let mut end_index = self.size; let mut start_index = end_index / 2; while start_index >= 1 { for i in start_index..end_index { self.merge(i); } end_index = start_index; start_index /= 2; } } fn merge(&mut self, node: usize) { let (left, right) = (node * 2, node * 2 + 1); let (l, r) = (&self.array[left], &self.array[right]); let (mut li, mut ri) = (0, 0); let mut merged = Vec::with_capacity(l.len() + r.len()); while li < l.len() || ri < r.len() { if li == l.len() { merged.push(r[ri]); ri += 1; } else if ri == r.len() { merged.push(l[li]); li += 1; } else if l[li] <= r[ri] { merged.push(l[li]); li += 1; } else { merged.push(r[ri]); ri += 1; } } self.array[node] = merged; } fn calc(&self, array: &[i64], x: i64) -> i64 { if array.is_empty() { return MAX_INT; } if x <= array[0] { return array[0] - x; } if x >= array[array.len() - 1] { return x - array[array.len() - 1]; } let mut low = 0; let mut high = array.len() - 1; while high - low > 1 { let mid = (high + low) / 2; if array[mid] <= x { low = mid; } else { high = mid; } } (x - array[low]).min(array[high] - x) } fn get_abs_min(&self, l: usize, r: usize, x: i64) -> i64 { let mut L = self.size + l; let mut R = self.size + r; let mut s = MAX_INT; while L < R { if R & 1 != 0 { R -= 1; s = s.min(self.calc(&self.array[R], x)); } if L & 1 != 0 { s = s.min(self.calc(&self.array[L], x)); L += 1; } L /= 2; R /= 2; } s } } fn main() { let stdin = io::stdin(); let mut lines = stdin.lock().lines(); let n: usize = lines.next().unwrap().unwrap().trim().parse().unwrap(); let x: Vec<i64> = lines .next() .unwrap() .unwrap() .split_whitespace() .map(|s| s.parse().unwrap()) .collect(); let q: usize = lines.next().unwrap().unwrap().trim().parse().unwrap(); let mut queries = Vec::with_capacity(q); for _ in 0..q { let parts: Vec<i64> = lines .next() .unwrap() .unwrap() .split_whitespace() .map(|s| s.parse().unwrap()) .collect(); queries.push((parts[0] as usize - 1, parts[1] as usize - 1, parts[2])); } let seg_tree = SegmentTree::new(&x); for (l, r, x) in queries { let ans = seg_tree.get_abs_min(l, r + 1, x); println!("{}", ans); } }