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