mirror of
https://gitlab.com/mfocko/Codeforces.git
synced 2025-05-03 09:52:59 +02:00
Merge branch '1851' into 'main'
1851(rs): solve contest See merge request mfocko/Codeforces!1
This commit is contained in:
commit
68dbe9c9c3
6 changed files with 2571 additions and 0 deletions
1279
1851/index.html
Normal file
1279
1851/index.html
Normal file
File diff suppressed because one or more lines are too long
236
1851/src/bin/a.rs
Normal file
236
1851/src/bin/a.rs
Normal file
|
@ -0,0 +1,236 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
// region ‹use›
|
||||
use self::input::*;
|
||||
use self::math::*;
|
||||
use self::output::*;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
// endregion ‹use›
|
||||
|
||||
fn can_talk_to(m: i64, k: i64, vh: i64, heights: Vec<i64>) -> usize {
|
||||
heights
|
||||
.iter()
|
||||
.filter(|&h| {
|
||||
if (vh - h) % k != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let diff = (vh - h) / k;
|
||||
|
||||
(1..=m)
|
||||
.filter(|a| 1 <= diff + a && diff + a <= m)
|
||||
.any(|a| diff + a != a)
|
||||
})
|
||||
.count()
|
||||
}
|
||||
|
||||
fn solve(s: &mut Scanner) {
|
||||
let (n, m, k, h) = (
|
||||
s.next::<usize>(),
|
||||
s.next::<i64>(),
|
||||
s.next::<i64>(),
|
||||
s.next::<i64>(),
|
||||
);
|
||||
let heights = s.next_vec::<i64>(n);
|
||||
println!("{}", can_talk_to(m, k, h, heights));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// region runner
|
||||
const SINGLE_TEST: bool = false;
|
||||
fn main() {
|
||||
let mut s = Scanner::new();
|
||||
|
||||
if SINGLE_TEST {
|
||||
solve(&mut s)
|
||||
} else {
|
||||
let n = s.next::<usize>();
|
||||
for _ in 0..n {
|
||||
solve(&mut s)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion runner
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod math {
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
pub fn add(a: i64, b: i64) -> i64 {
|
||||
(a + b) % MOD
|
||||
}
|
||||
|
||||
pub fn sub(a: i64, b: i64) -> i64 {
|
||||
((a - b) % MOD + MOD) % MOD
|
||||
}
|
||||
|
||||
pub fn mul(a: i64, b: i64) -> i64 {
|
||||
(a * b) % MOD
|
||||
}
|
||||
|
||||
pub fn exp(b: i64, e: i64) -> i64 {
|
||||
if e == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let half = exp(b, e / 2);
|
||||
if e % 2 == 0 {
|
||||
return mul(half, half);
|
||||
}
|
||||
|
||||
mul(half, mul(half, b))
|
||||
}
|
||||
|
||||
/// A trait implementing the unsigned bit shifts.
|
||||
pub trait UnsignedShift {
|
||||
fn unsigned_shl(self, n: u32) -> Self;
|
||||
fn unsigned_shr(self, n: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implementing the integer square root.
|
||||
pub trait ISqrt {
|
||||
fn isqrt(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.isqrt_checked()
|
||||
.expect("cannot calculate square root of negative number")
|
||||
}
|
||||
|
||||
fn isqrt_checked(&self) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
macro_rules! math_traits_impl {
|
||||
($T:ty, $U: ty) => {
|
||||
impl UnsignedShift for $T {
|
||||
#[inline]
|
||||
fn unsigned_shl(self, n: u32) -> Self {
|
||||
((self as $U) << n) as $T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unsigned_shr(self, n: u32) -> Self {
|
||||
((self as $U) >> n) as $T
|
||||
}
|
||||
}
|
||||
|
||||
impl ISqrt for $T {
|
||||
#[inline]
|
||||
fn isqrt_checked(&self) -> Option<Self> {
|
||||
use core::cmp::Ordering;
|
||||
match self.cmp(&<$T>::default()) {
|
||||
// Hopefully this will be stripped for unsigned numbers (impossible condition)
|
||||
Ordering::Less => return None,
|
||||
Ordering::Equal => return Some(<$T>::default()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Compute bit, the largest power of 4 <= n
|
||||
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
|
||||
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
|
||||
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
|
||||
|
||||
// Algorithm based on the implementation in:
|
||||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
|
||||
// Note that result/bit are logically unsigned (even if T is signed).
|
||||
let mut n = *self;
|
||||
let mut result = <$T>::default();
|
||||
while bit != <$T>::default() {
|
||||
if n >= (result + bit) {
|
||||
n -= result + bit;
|
||||
result = result.unsigned_shr(1) + bit;
|
||||
} else {
|
||||
result = result.unsigned_shr(1);
|
||||
}
|
||||
bit = bit.unsigned_shr(2);
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
math_traits_impl!(i8, u8);
|
||||
math_traits_impl!(u8, u8);
|
||||
math_traits_impl!(i16, u16);
|
||||
math_traits_impl!(u16, u16);
|
||||
math_traits_impl!(i32, u32);
|
||||
math_traits_impl!(u32, u32);
|
||||
math_traits_impl!(i64, u64);
|
||||
math_traits_impl!(u64, u64);
|
||||
math_traits_impl!(i128, u128);
|
||||
math_traits_impl!(u128, u128);
|
||||
math_traits_impl!(isize, usize);
|
||||
math_traits_impl!(usize, usize);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod output {
|
||||
pub fn yes() {
|
||||
println!("YES");
|
||||
}
|
||||
|
||||
pub fn no() {
|
||||
println!("NO");
|
||||
}
|
||||
|
||||
pub fn yesno(ans: bool) {
|
||||
println!("{}", if ans { "YES" } else { "NO" });
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod input {
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct Scanner {
|
||||
buffer: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new() -> Scanner {
|
||||
Scanner {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next<T: FromStr>(&mut self) -> T {
|
||||
if self.buffer.is_empty() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_line(&mut input).ok();
|
||||
|
||||
for word in input.split_whitespace() {
|
||||
self.buffer.push_back(word.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let front = self.buffer.pop_front().unwrap();
|
||||
front.parse::<T>().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
|
||||
let mut arr = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
arr.push(self.next::<T>());
|
||||
}
|
||||
|
||||
arr
|
||||
}
|
||||
}
|
||||
}
|
244
1851/src/bin/b.rs
Normal file
244
1851/src/bin/b.rs
Normal file
|
@ -0,0 +1,244 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
// region ‹use›
|
||||
use self::input::*;
|
||||
use self::math::*;
|
||||
use self::output::*;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
// endregion ‹use›
|
||||
|
||||
fn can_sort(nums: Vec<i32>) -> bool {
|
||||
let mut sorted_nums = nums.clone();
|
||||
sorted_nums.sort();
|
||||
|
||||
nums.iter()
|
||||
.zip(sorted_nums.iter())
|
||||
.all(|(src, dst)| src % 2 == dst % 2)
|
||||
}
|
||||
|
||||
fn solve(s: &mut Scanner) {
|
||||
let n = s.next::<usize>();
|
||||
let nums = s.next_vec::<i32>(n);
|
||||
|
||||
yesno(can_sort(nums));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert!(can_sort(vec![7, 10, 1, 3, 2]));
|
||||
}
|
||||
#[test]
|
||||
fn example_2() {
|
||||
assert!(can_sort(vec![11, 9, 3, 5]));
|
||||
}
|
||||
#[test]
|
||||
fn example_3() {
|
||||
assert!(!can_sort(vec![11, 3, 15, 3, 2]));
|
||||
}
|
||||
#[test]
|
||||
fn example_4() {
|
||||
assert!(!can_sort(vec![10, 7, 8, 1, 2, 3]));
|
||||
}
|
||||
#[test]
|
||||
fn example_5() {
|
||||
assert!(can_sort(vec![10]));
|
||||
}
|
||||
#[test]
|
||||
fn example_6() {
|
||||
assert!(!can_sort(vec![6, 6, 4, 1, 6]));
|
||||
}
|
||||
}
|
||||
|
||||
// region runner
|
||||
const SINGLE_TEST: bool = false;
|
||||
fn main() {
|
||||
let mut s = Scanner::new();
|
||||
|
||||
if SINGLE_TEST {
|
||||
solve(&mut s)
|
||||
} else {
|
||||
let n = s.next::<usize>();
|
||||
for _ in 0..n {
|
||||
solve(&mut s)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion runner
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod math {
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
pub fn add(a: i64, b: i64) -> i64 {
|
||||
(a + b) % MOD
|
||||
}
|
||||
|
||||
pub fn sub(a: i64, b: i64) -> i64 {
|
||||
((a - b) % MOD + MOD) % MOD
|
||||
}
|
||||
|
||||
pub fn mul(a: i64, b: i64) -> i64 {
|
||||
(a * b) % MOD
|
||||
}
|
||||
|
||||
pub fn exp(b: i64, e: i64) -> i64 {
|
||||
if e == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let half = exp(b, e / 2);
|
||||
if e % 2 == 0 {
|
||||
return mul(half, half);
|
||||
}
|
||||
|
||||
mul(half, mul(half, b))
|
||||
}
|
||||
|
||||
/// A trait implementing the unsigned bit shifts.
|
||||
pub trait UnsignedShift {
|
||||
fn unsigned_shl(self, n: u32) -> Self;
|
||||
fn unsigned_shr(self, n: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implementing the integer square root.
|
||||
pub trait ISqrt {
|
||||
fn isqrt(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.isqrt_checked()
|
||||
.expect("cannot calculate square root of negative number")
|
||||
}
|
||||
|
||||
fn isqrt_checked(&self) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
macro_rules! math_traits_impl {
|
||||
($T:ty, $U: ty) => {
|
||||
impl UnsignedShift for $T {
|
||||
#[inline]
|
||||
fn unsigned_shl(self, n: u32) -> Self {
|
||||
((self as $U) << n) as $T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unsigned_shr(self, n: u32) -> Self {
|
||||
((self as $U) >> n) as $T
|
||||
}
|
||||
}
|
||||
|
||||
impl ISqrt for $T {
|
||||
#[inline]
|
||||
fn isqrt_checked(&self) -> Option<Self> {
|
||||
use core::cmp::Ordering;
|
||||
match self.cmp(&<$T>::default()) {
|
||||
// Hopefully this will be stripped for unsigned numbers (impossible condition)
|
||||
Ordering::Less => return None,
|
||||
Ordering::Equal => return Some(<$T>::default()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Compute bit, the largest power of 4 <= n
|
||||
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
|
||||
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
|
||||
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
|
||||
|
||||
// Algorithm based on the implementation in:
|
||||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
|
||||
// Note that result/bit are logically unsigned (even if T is signed).
|
||||
let mut n = *self;
|
||||
let mut result = <$T>::default();
|
||||
while bit != <$T>::default() {
|
||||
if n >= (result + bit) {
|
||||
n -= result + bit;
|
||||
result = result.unsigned_shr(1) + bit;
|
||||
} else {
|
||||
result = result.unsigned_shr(1);
|
||||
}
|
||||
bit = bit.unsigned_shr(2);
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
math_traits_impl!(i8, u8);
|
||||
math_traits_impl!(u8, u8);
|
||||
math_traits_impl!(i16, u16);
|
||||
math_traits_impl!(u16, u16);
|
||||
math_traits_impl!(i32, u32);
|
||||
math_traits_impl!(u32, u32);
|
||||
math_traits_impl!(i64, u64);
|
||||
math_traits_impl!(u64, u64);
|
||||
math_traits_impl!(i128, u128);
|
||||
math_traits_impl!(u128, u128);
|
||||
math_traits_impl!(isize, usize);
|
||||
math_traits_impl!(usize, usize);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod output {
|
||||
pub fn yes() {
|
||||
println!("YES");
|
||||
}
|
||||
|
||||
pub fn no() {
|
||||
println!("NO");
|
||||
}
|
||||
|
||||
pub fn yesno(ans: bool) {
|
||||
println!("{}", if ans { "YES" } else { "NO" });
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod input {
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct Scanner {
|
||||
buffer: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new() -> Scanner {
|
||||
Scanner {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next<T: FromStr>(&mut self) -> T {
|
||||
if self.buffer.is_empty() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_line(&mut input).ok();
|
||||
|
||||
for word in input.split_whitespace() {
|
||||
self.buffer.push_back(word.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let front = self.buffer.pop_front().unwrap();
|
||||
front.parse::<T>().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
|
||||
let mut arr = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
arr.push(self.next::<T>());
|
||||
}
|
||||
|
||||
arr
|
||||
}
|
||||
}
|
||||
}
|
253
1851/src/bin/c.rs
Normal file
253
1851/src/bin/c.rs
Normal file
|
@ -0,0 +1,253 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
// region ‹use›
|
||||
use self::input::*;
|
||||
use self::math::*;
|
||||
use self::output::*;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
// endregion ‹use›
|
||||
|
||||
fn exists_path(k: usize, tiles: Vec<i32>) -> bool {
|
||||
let first = *tiles.first().expect("at least one tile");
|
||||
let last = *tiles.last().expect("at least one tiles");
|
||||
|
||||
// dbg!(first, last);
|
||||
|
||||
let tiles_of_first = tiles.iter().filter(|&&t| t == first).count();
|
||||
let tiles_of_last = tiles.iter().filter(|&&t| t == last).count();
|
||||
|
||||
// dbg!(tiles_of_first, tiles_of_last);
|
||||
|
||||
let last_of_first = tiles
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, &c)| c == first)
|
||||
.nth(k - 1)
|
||||
.map(|(i, _)| i)
|
||||
.unwrap_or(tiles.len());
|
||||
let first_of_last = tiles
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.filter(|(_, &c)| c == last)
|
||||
.nth(k - 1)
|
||||
.map(|(i, _)| i)
|
||||
.unwrap_or(0);
|
||||
|
||||
// dbg!(last_of_first, first_of_last);
|
||||
|
||||
tiles.len() >= k
|
||||
&& ((first == last && tiles_of_first >= k)
|
||||
|| (first != last
|
||||
&& tiles_of_first >= k
|
||||
&& tiles_of_last >= k
|
||||
&& last_of_first < first_of_last))
|
||||
}
|
||||
|
||||
fn solve(s: &mut Scanner) {
|
||||
let n = s.next::<usize>();
|
||||
let k = s.next::<usize>();
|
||||
let tiles = s.next_vec::<i32>(n);
|
||||
|
||||
yesno(exists_path(k, tiles));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// region runner
|
||||
const SINGLE_TEST: bool = false;
|
||||
fn main() {
|
||||
let mut s = Scanner::new();
|
||||
|
||||
if SINGLE_TEST {
|
||||
solve(&mut s)
|
||||
} else {
|
||||
let n = s.next::<usize>();
|
||||
for _ in 0..n {
|
||||
solve(&mut s)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion runner
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod math {
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
pub fn add(a: i64, b: i64) -> i64 {
|
||||
(a + b) % MOD
|
||||
}
|
||||
|
||||
pub fn sub(a: i64, b: i64) -> i64 {
|
||||
((a - b) % MOD + MOD) % MOD
|
||||
}
|
||||
|
||||
pub fn mul(a: i64, b: i64) -> i64 {
|
||||
(a * b) % MOD
|
||||
}
|
||||
|
||||
pub fn exp(b: i64, e: i64) -> i64 {
|
||||
if e == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let half = exp(b, e / 2);
|
||||
if e % 2 == 0 {
|
||||
return mul(half, half);
|
||||
}
|
||||
|
||||
mul(half, mul(half, b))
|
||||
}
|
||||
|
||||
/// A trait implementing the unsigned bit shifts.
|
||||
pub trait UnsignedShift {
|
||||
fn unsigned_shl(self, n: u32) -> Self;
|
||||
fn unsigned_shr(self, n: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implementing the integer square root.
|
||||
pub trait ISqrt {
|
||||
fn isqrt(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.isqrt_checked()
|
||||
.expect("cannot calculate square root of negative number")
|
||||
}
|
||||
|
||||
fn isqrt_checked(&self) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
macro_rules! math_traits_impl {
|
||||
($T:ty, $U: ty) => {
|
||||
impl UnsignedShift for $T {
|
||||
#[inline]
|
||||
fn unsigned_shl(self, n: u32) -> Self {
|
||||
((self as $U) << n) as $T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unsigned_shr(self, n: u32) -> Self {
|
||||
((self as $U) >> n) as $T
|
||||
}
|
||||
}
|
||||
|
||||
impl ISqrt for $T {
|
||||
#[inline]
|
||||
fn isqrt_checked(&self) -> Option<Self> {
|
||||
use core::cmp::Ordering;
|
||||
match self.cmp(&<$T>::default()) {
|
||||
// Hopefully this will be stripped for unsigned numbers (impossible condition)
|
||||
Ordering::Less => return None,
|
||||
Ordering::Equal => return Some(<$T>::default()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Compute bit, the largest power of 4 <= n
|
||||
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
|
||||
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
|
||||
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
|
||||
|
||||
// Algorithm based on the implementation in:
|
||||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
|
||||
// Note that result/bit are logically unsigned (even if T is signed).
|
||||
let mut n = *self;
|
||||
let mut result = <$T>::default();
|
||||
while bit != <$T>::default() {
|
||||
if n >= (result + bit) {
|
||||
n -= result + bit;
|
||||
result = result.unsigned_shr(1) + bit;
|
||||
} else {
|
||||
result = result.unsigned_shr(1);
|
||||
}
|
||||
bit = bit.unsigned_shr(2);
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
math_traits_impl!(i8, u8);
|
||||
math_traits_impl!(u8, u8);
|
||||
math_traits_impl!(i16, u16);
|
||||
math_traits_impl!(u16, u16);
|
||||
math_traits_impl!(i32, u32);
|
||||
math_traits_impl!(u32, u32);
|
||||
math_traits_impl!(i64, u64);
|
||||
math_traits_impl!(u64, u64);
|
||||
math_traits_impl!(i128, u128);
|
||||
math_traits_impl!(u128, u128);
|
||||
math_traits_impl!(isize, usize);
|
||||
math_traits_impl!(usize, usize);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod output {
|
||||
pub fn yes() {
|
||||
println!("YES");
|
||||
}
|
||||
|
||||
pub fn no() {
|
||||
println!("NO");
|
||||
}
|
||||
|
||||
pub fn yesno(ans: bool) {
|
||||
println!("{}", if ans { "YES" } else { "NO" });
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod input {
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct Scanner {
|
||||
buffer: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new() -> Scanner {
|
||||
Scanner {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next<T: FromStr>(&mut self) -> T {
|
||||
if self.buffer.is_empty() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_line(&mut input).ok();
|
||||
|
||||
for word in input.split_whitespace() {
|
||||
self.buffer.push_back(word.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let front = self.buffer.pop_front().unwrap();
|
||||
front.parse::<T>().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
|
||||
let mut arr = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
arr.push(self.next::<T>());
|
||||
}
|
||||
|
||||
arr
|
||||
}
|
||||
}
|
||||
}
|
223
1851/src/bin/d.rs
Normal file
223
1851/src/bin/d.rs
Normal file
|
@ -0,0 +1,223 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
// region ‹use›
|
||||
use self::input::*;
|
||||
use self::math::*;
|
||||
use self::output::*;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
// endregion ‹use›
|
||||
|
||||
fn perm_exists(a: Vec<i64>) -> bool {
|
||||
let mut diffs: Vec<i64> = a.iter().zip(a.iter().skip(1)).map(|(y, x)| x - y).collect();
|
||||
diffs.sort();
|
||||
|
||||
dbg!(diffs);
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn solve(s: &mut Scanner) {
|
||||
let n = s.next::<usize>();
|
||||
let prefix = s.next_vec::<i64>(n - 1);
|
||||
yesno(perm_exists(prefix));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// region runner
|
||||
const SINGLE_TEST: bool = false;
|
||||
fn main() {
|
||||
let mut s = Scanner::new();
|
||||
|
||||
if SINGLE_TEST {
|
||||
solve(&mut s)
|
||||
} else {
|
||||
let n = s.next::<usize>();
|
||||
for _ in 0..n {
|
||||
solve(&mut s)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion runner
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod math {
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
pub fn add(a: i64, b: i64) -> i64 {
|
||||
(a + b) % MOD
|
||||
}
|
||||
|
||||
pub fn sub(a: i64, b: i64) -> i64 {
|
||||
((a - b) % MOD + MOD) % MOD
|
||||
}
|
||||
|
||||
pub fn mul(a: i64, b: i64) -> i64 {
|
||||
(a * b) % MOD
|
||||
}
|
||||
|
||||
pub fn exp(b: i64, e: i64) -> i64 {
|
||||
if e == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let half = exp(b, e / 2);
|
||||
if e % 2 == 0 {
|
||||
return mul(half, half);
|
||||
}
|
||||
|
||||
mul(half, mul(half, b))
|
||||
}
|
||||
|
||||
/// A trait implementing the unsigned bit shifts.
|
||||
pub trait UnsignedShift {
|
||||
fn unsigned_shl(self, n: u32) -> Self;
|
||||
fn unsigned_shr(self, n: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implementing the integer square root.
|
||||
pub trait ISqrt {
|
||||
fn isqrt(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.isqrt_checked()
|
||||
.expect("cannot calculate square root of negative number")
|
||||
}
|
||||
|
||||
fn isqrt_checked(&self) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
macro_rules! math_traits_impl {
|
||||
($T:ty, $U: ty) => {
|
||||
impl UnsignedShift for $T {
|
||||
#[inline]
|
||||
fn unsigned_shl(self, n: u32) -> Self {
|
||||
((self as $U) << n) as $T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unsigned_shr(self, n: u32) -> Self {
|
||||
((self as $U) >> n) as $T
|
||||
}
|
||||
}
|
||||
|
||||
impl ISqrt for $T {
|
||||
#[inline]
|
||||
fn isqrt_checked(&self) -> Option<Self> {
|
||||
use core::cmp::Ordering;
|
||||
match self.cmp(&<$T>::default()) {
|
||||
// Hopefully this will be stripped for unsigned numbers (impossible condition)
|
||||
Ordering::Less => return None,
|
||||
Ordering::Equal => return Some(<$T>::default()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Compute bit, the largest power of 4 <= n
|
||||
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
|
||||
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
|
||||
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
|
||||
|
||||
// Algorithm based on the implementation in:
|
||||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
|
||||
// Note that result/bit are logically unsigned (even if T is signed).
|
||||
let mut n = *self;
|
||||
let mut result = <$T>::default();
|
||||
while bit != <$T>::default() {
|
||||
if n >= (result + bit) {
|
||||
n -= result + bit;
|
||||
result = result.unsigned_shr(1) + bit;
|
||||
} else {
|
||||
result = result.unsigned_shr(1);
|
||||
}
|
||||
bit = bit.unsigned_shr(2);
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
math_traits_impl!(i8, u8);
|
||||
math_traits_impl!(u8, u8);
|
||||
math_traits_impl!(i16, u16);
|
||||
math_traits_impl!(u16, u16);
|
||||
math_traits_impl!(i32, u32);
|
||||
math_traits_impl!(u32, u32);
|
||||
math_traits_impl!(i64, u64);
|
||||
math_traits_impl!(u64, u64);
|
||||
math_traits_impl!(i128, u128);
|
||||
math_traits_impl!(u128, u128);
|
||||
math_traits_impl!(isize, usize);
|
||||
math_traits_impl!(usize, usize);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod output {
|
||||
pub fn yes() {
|
||||
println!("YES");
|
||||
}
|
||||
|
||||
pub fn no() {
|
||||
println!("NO");
|
||||
}
|
||||
|
||||
pub fn yesno(ans: bool) {
|
||||
println!("{}", if ans { "YES" } else { "NO" });
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod input {
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct Scanner {
|
||||
buffer: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new() -> Scanner {
|
||||
Scanner {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next<T: FromStr>(&mut self) -> T {
|
||||
if self.buffer.is_empty() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_line(&mut input).ok();
|
||||
|
||||
for word in input.split_whitespace() {
|
||||
self.buffer.push_back(word.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let front = self.buffer.pop_front().unwrap();
|
||||
front.parse::<T>().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
|
||||
let mut arr = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
arr.push(self.next::<T>());
|
||||
}
|
||||
|
||||
arr
|
||||
}
|
||||
}
|
||||
}
|
336
1851/src/bin/e.rs
Normal file
336
1851/src/bin/e.rs
Normal file
|
@ -0,0 +1,336 @@
|
|||
#![allow(unused_imports)]
|
||||
|
||||
// region ‹use›
|
||||
use self::data_structures::*;
|
||||
use self::input::*;
|
||||
use self::math::*;
|
||||
use self::output::*;
|
||||
use std::cmp::{max, min};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
// endregion ‹use›
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
struct Way {
|
||||
required: Vec<usize>,
|
||||
}
|
||||
|
||||
impl Way {
|
||||
fn estimated_cost(&self, costs: &[u64]) -> u64 {
|
||||
if self.required.is_empty() {
|
||||
return u64::MAX;
|
||||
}
|
||||
|
||||
self.required.iter().map(|i| costs[i - 1]).sum()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Mark {
|
||||
None,
|
||||
Temporary,
|
||||
Permanent,
|
||||
}
|
||||
|
||||
fn toposort(ways: &[Way], marks: &mut Vec<Mark>) -> Vec<usize> {
|
||||
fn visit(ways: &[Way], marks: &mut Vec<Mark>, ordering: &mut Vec<usize>, u: usize) {
|
||||
match marks[u] {
|
||||
Mark::None => {
|
||||
marks[u] = Mark::Temporary;
|
||||
|
||||
for v in &ways[u].required {
|
||||
visit(ways, marks, ordering, v - 1);
|
||||
}
|
||||
|
||||
marks[u] = Mark::Permanent;
|
||||
ordering.push(u);
|
||||
}
|
||||
Mark::Temporary => unreachable!("no loops should be present"),
|
||||
Mark::Permanent => { /* no-op */ }
|
||||
}
|
||||
}
|
||||
|
||||
let mut ordering = vec![];
|
||||
|
||||
for i in 0..marks.len() {
|
||||
visit(ways, marks, &mut ordering, i);
|
||||
}
|
||||
|
||||
ordering
|
||||
}
|
||||
|
||||
fn find_costs(costs: &mut Vec<u64>, unlimited: Vec<usize>, ways: Vec<Way>) {
|
||||
let mut marks = vec![Mark::None; costs.len()];
|
||||
|
||||
// set cost of unlimited
|
||||
for i in unlimited {
|
||||
costs[i - 1] = 0;
|
||||
marks[i - 1] = Mark::Permanent;
|
||||
}
|
||||
|
||||
// set cost of inconstructible
|
||||
for (i, way) in ways.iter().enumerate() {
|
||||
if way.estimated_cost(costs) == u64::MAX {
|
||||
marks[i] = Mark::Permanent;
|
||||
}
|
||||
}
|
||||
|
||||
// do toposort to find the ideal order
|
||||
for i in toposort(&ways, &mut marks) {
|
||||
costs[i] = min(costs[i], ways[i].estimated_cost(costs));
|
||||
}
|
||||
}
|
||||
|
||||
fn solve(s: &mut Scanner) {
|
||||
let n = s.next::<usize>();
|
||||
let k = s.next::<usize>();
|
||||
|
||||
let mut costs = s.next_vec::<u64>(n);
|
||||
let unlimited = s.next_vec::<usize>(k);
|
||||
|
||||
let ways = (0..n)
|
||||
.map(|_| {
|
||||
let m = s.next::<usize>();
|
||||
Way {
|
||||
required: s.next_vec::<usize>(m),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
find_costs(&mut costs, unlimited, ways);
|
||||
|
||||
let costs: Vec<String> = costs.iter().map(|c| format!("{}", c)).collect();
|
||||
println!("{}", &costs.join(" "));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn example_1() {
|
||||
assert_eq!(1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// region runner
|
||||
const SINGLE_TEST: bool = false;
|
||||
fn main() {
|
||||
let mut s = Scanner::new();
|
||||
|
||||
if SINGLE_TEST {
|
||||
solve(&mut s)
|
||||
} else {
|
||||
let n = s.next::<usize>();
|
||||
for _ in 0..n {
|
||||
solve(&mut s)
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion runner
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod math {
|
||||
const MOD: i64 = 1_000_000_007;
|
||||
|
||||
pub fn add(a: i64, b: i64) -> i64 {
|
||||
(a + b) % MOD
|
||||
}
|
||||
|
||||
pub fn sub(a: i64, b: i64) -> i64 {
|
||||
((a - b) % MOD + MOD) % MOD
|
||||
}
|
||||
|
||||
pub fn mul(a: i64, b: i64) -> i64 {
|
||||
(a * b) % MOD
|
||||
}
|
||||
|
||||
pub fn exp(b: i64, e: i64) -> i64 {
|
||||
if e == 0 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let half = exp(b, e / 2);
|
||||
if e % 2 == 0 {
|
||||
return mul(half, half);
|
||||
}
|
||||
|
||||
mul(half, mul(half, b))
|
||||
}
|
||||
|
||||
/// A trait implementing the unsigned bit shifts.
|
||||
pub trait UnsignedShift {
|
||||
fn unsigned_shl(self, n: u32) -> Self;
|
||||
fn unsigned_shr(self, n: u32) -> Self;
|
||||
}
|
||||
|
||||
/// A trait implementing the integer square root.
|
||||
pub trait ISqrt {
|
||||
fn isqrt(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.isqrt_checked()
|
||||
.expect("cannot calculate square root of negative number")
|
||||
}
|
||||
|
||||
fn isqrt_checked(&self) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
macro_rules! math_traits_impl {
|
||||
($T:ty, $U: ty) => {
|
||||
impl UnsignedShift for $T {
|
||||
#[inline]
|
||||
fn unsigned_shl(self, n: u32) -> Self {
|
||||
((self as $U) << n) as $T
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unsigned_shr(self, n: u32) -> Self {
|
||||
((self as $U) >> n) as $T
|
||||
}
|
||||
}
|
||||
|
||||
impl ISqrt for $T {
|
||||
#[inline]
|
||||
fn isqrt_checked(&self) -> Option<Self> {
|
||||
use core::cmp::Ordering;
|
||||
match self.cmp(&<$T>::default()) {
|
||||
// Hopefully this will be stripped for unsigned numbers (impossible condition)
|
||||
Ordering::Less => return None,
|
||||
Ordering::Equal => return Some(<$T>::default()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Compute bit, the largest power of 4 <= n
|
||||
let max_shift: u32 = <$T>::default().leading_zeros() - 1;
|
||||
let shift: u32 = (max_shift - self.leading_zeros()) & !1;
|
||||
let mut bit = <$T>::try_from(1).unwrap().unsigned_shl(shift);
|
||||
|
||||
// Algorithm based on the implementation in:
|
||||
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)
|
||||
// Note that result/bit are logically unsigned (even if T is signed).
|
||||
let mut n = *self;
|
||||
let mut result = <$T>::default();
|
||||
while bit != <$T>::default() {
|
||||
if n >= (result + bit) {
|
||||
n -= result + bit;
|
||||
result = result.unsigned_shr(1) + bit;
|
||||
} else {
|
||||
result = result.unsigned_shr(1);
|
||||
}
|
||||
bit = bit.unsigned_shr(2);
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
math_traits_impl!(i8, u8);
|
||||
math_traits_impl!(u8, u8);
|
||||
math_traits_impl!(i16, u16);
|
||||
math_traits_impl!(u16, u16);
|
||||
math_traits_impl!(i32, u32);
|
||||
math_traits_impl!(u32, u32);
|
||||
math_traits_impl!(i64, u64);
|
||||
math_traits_impl!(u64, u64);
|
||||
math_traits_impl!(i128, u128);
|
||||
math_traits_impl!(u128, u128);
|
||||
math_traits_impl!(isize, usize);
|
||||
math_traits_impl!(usize, usize);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod data_structures {
|
||||
use std::cmp::{Ord, Reverse};
|
||||
use std::collections::BinaryHeap;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MinHeap<T> {
|
||||
heap: BinaryHeap<Reverse<T>>,
|
||||
}
|
||||
|
||||
impl<T: Ord> MinHeap<T> {
|
||||
pub fn new() -> MinHeap<T> {
|
||||
MinHeap {
|
||||
heap: BinaryHeap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, item: T) {
|
||||
self.heap.push(Reverse(item))
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.heap.pop().map(|Reverse(x)| x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord> Default for MinHeap<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod output {
|
||||
pub fn yes() {
|
||||
println!("YES");
|
||||
}
|
||||
|
||||
pub fn no() {
|
||||
println!("NO");
|
||||
}
|
||||
|
||||
pub fn yesno(ans: bool) {
|
||||
println!("{}", if ans { "YES" } else { "NO" });
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
mod input {
|
||||
use std::collections::VecDeque;
|
||||
use std::io;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct Scanner {
|
||||
buffer: VecDeque<String>,
|
||||
}
|
||||
|
||||
impl Scanner {
|
||||
pub fn new() -> Scanner {
|
||||
Scanner {
|
||||
buffer: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next<T: FromStr>(&mut self) -> T {
|
||||
if self.buffer.is_empty() {
|
||||
let mut input = String::new();
|
||||
|
||||
io::stdin().read_line(&mut input).ok();
|
||||
|
||||
for word in input.split_whitespace() {
|
||||
self.buffer.push_back(word.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
let front = self.buffer.pop_front().unwrap();
|
||||
front.parse::<T>().ok().unwrap()
|
||||
}
|
||||
|
||||
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
|
||||
let mut arr = vec![];
|
||||
|
||||
for _ in 0..n {
|
||||
arr.push(self.next::<T>());
|
||||
}
|
||||
|
||||
arr
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue