結果
| 問題 |
No.2658 L-R Nim
|
| コンテスト | |
| ユーザー |
akakimidori
|
| 提出日時 | 2024-03-01 23:02:49 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 1,964 ms / 7,000 ms |
| コード長 | 6,211 bytes |
| コンパイル時間 | 17,226 ms |
| コンパイル使用メモリ | 403,156 KB |
| 実行使用メモリ | 327,424 KB |
| 最終ジャッジ日時 | 2024-09-29 14:48:52 |
| 合計ジャッジ時間 | 65,638 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 48 |
コンパイルメッセージ
warning: unused import: `std::io::Write` --> src/main.rs:4:5 | 4 | use std::io::Write; | ^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: type alias `Set` is never used --> src/main.rs:8:6 | 8 | type Set<T> = BTreeSet<T>; | ^^^ | = note: `#[warn(dead_code)]` on by default warning: type alias `Deque` is never used --> src/main.rs:9:6 | 9 | type Deque<T> = VecDeque<T>; | ^^^^^
ソースコード
// 累積xorが一致しないようにしたい
//
use std::io::Write;
use std::collections::*;
type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;
fn main() {
input! {
n: usize,
k: usize,
a: [usize; n],
}
let mut map = Map::new();
for (i, &a) in a.iter().enumerate() {
let mut x = vec![0];
for i in 1..=k {
if i < a {
x.push(a ^ (a - i));
}
x.push(a ^ (a + i));
}
x.sort();
x.dedup();
for x in x {
map.entry(x).or_insert(vec![]).push(i);
}
}
let mut ban = Map::new();
let mut last = vec![None; 1 << 21];
last[0] = Some(n);
let mut xor = 0;
let mut r = n;
let mut l = 0;
for (i, a) in a.iter().enumerate().rev() {
xor ^= a;
for &x in map.keys() {
if let Some(y) = last[xor ^ x] {
ban.entry(x).or_insert(vec![]).push((i, y));
}
}
if let Some(y) = last[xor] {
l = l.max(i);
r = r.min(y);
}
last[xor] = Some(i);
}
if l >= r {
println!("No");
return;
}
for (x, pos) in map {
let po = ban.entry(x).or_insert(vec![]);
po.sort_by_key(|p| (p.0, !p.1));
po.dedup_by(|a, b| b.1 >= a.0 && {
b.1 = b.1.max(a.1);
true
});
for &pos in pos.iter() {
if !(l <= pos && pos < r) {
continue;
}
let u = po.upper_bound_by_key(&pos, |p| p.0);
if u == 0 || po[u - 1].1 <= pos {
println!("Yes");
return;
}
}
}
println!("No");
}
// ---------- begin input macro ----------
// reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[macro_export]
macro_rules! input {
(source = $s:expr, $($r:tt)*) => {
let mut iter = $s.split_whitespace();
input_inner!{iter, $($r)*}
};
($($r:tt)*) => {
let s = {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
s
};
let mut iter = s.split_whitespace();
input_inner!{iter, $($r)*}
};
}
#[macro_export]
macro_rules! input_inner {
($iter:expr) => {};
($iter:expr, ) => {};
($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($iter, $t);
input_inner!{$iter $($r)*}
};
}
#[macro_export]
macro_rules! read_value {
($iter:expr, ( $($t:tt),* )) => {
( $(read_value!($iter, $t)),* )
};
($iter:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
};
($iter:expr, chars) => {
read_value!($iter, String).chars().collect::<Vec<char>>()
};
($iter:expr, bytes) => {
read_value!($iter, String).bytes().collect::<Vec<u8>>()
};
($iter:expr, usize1) => {
read_value!($iter, usize) - 1
};
($iter:expr, $t:ty) => {
$iter.next().unwrap().parse::<$t>().expect("Parse error")
};
}
// ---------- end input macro ----------
// ---------- begin super slice ----------
pub trait SuperSlice {
type Item;
fn lower_bound(&self, key: &Self::Item) -> usize
where
Self::Item: Ord;
fn lower_bound_by<F>(&self, f: F) -> usize
where
F: FnMut(&Self::Item) -> std::cmp::Ordering;
fn lower_bound_by_key<K, F>(&self, key: &K, f: F) -> usize
where
K: Ord,
F: FnMut(&Self::Item) -> K;
fn upper_bound(&self, key: &Self::Item) -> usize
where
Self::Item: Ord;
fn upper_bound_by<F>(&self, f: F) -> usize
where
F: FnMut(&Self::Item) -> std::cmp::Ordering;
fn upper_bound_by_key<K, F>(&self, key: &K, f: F) -> usize
where
K: Ord,
F: FnMut(&Self::Item) -> K;
fn next_permutation(&mut self) -> bool
where
Self::Item: Ord;
fn next_permutation_by<F>(&mut self, f: F) -> bool
where
F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering;
fn prev_permutation(&mut self) -> bool
where
Self::Item: Ord;
}
impl<T> SuperSlice for [T] {
type Item = T;
fn lower_bound(&self, key: &Self::Item) -> usize
where
T: Ord,
{
self.lower_bound_by(|p| p.cmp(key))
}
fn lower_bound_by<F>(&self, mut f: F) -> usize
where
F: FnMut(&Self::Item) -> std::cmp::Ordering,
{
self.binary_search_by(|p| f(p).then(std::cmp::Ordering::Greater))
.unwrap_err()
}
fn lower_bound_by_key<K, F>(&self, key: &K, mut f: F) -> usize
where
K: Ord,
F: FnMut(&Self::Item) -> K,
{
self.lower_bound_by(|p| f(p).cmp(key))
}
fn upper_bound(&self, key: &Self::Item) -> usize
where
T: Ord,
{
self.upper_bound_by(|p| p.cmp(key))
}
fn upper_bound_by<F>(&self, mut f: F) -> usize
where
F: FnMut(&Self::Item) -> std::cmp::Ordering,
{
self.binary_search_by(|p| f(p).then(std::cmp::Ordering::Less))
.unwrap_err()
}
fn upper_bound_by_key<K, F>(&self, key: &K, mut f: F) -> usize
where
K: Ord,
F: FnMut(&Self::Item) -> K,
{
self.upper_bound_by(|p| f(p).cmp(key))
}
fn next_permutation(&mut self) -> bool
where
T: Ord,
{
self.next_permutation_by(|a, b| a.cmp(b))
}
fn next_permutation_by<F>(&mut self, mut f: F) -> bool
where
F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,
{
use std::cmp::Ordering::*;
if let Some(x) = self.windows(2).rposition(|a| f(&a[0], &a[1]) == Less) {
let y = self.iter().rposition(|b| f(&self[x], b) == Less).unwrap();
self.swap(x, y);
self[(x + 1)..].reverse();
true
} else {
self.reverse();
false
}
}
fn prev_permutation(&mut self) -> bool
where
T: Ord,
{
self.next_permutation_by(|a, b| a.cmp(b).reverse())
}
}
// ---------- end super slice ----------
akakimidori