結果
問題 | No.2382 Amidakuji M |
ユーザー |
|
提出日時 | 2023-07-14 22:44:59 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 77 ms / 2,000 ms |
コード長 | 9,712 bytes |
コンパイル時間 | 16,850 ms |
コンパイル使用メモリ | 378,064 KB |
実行使用メモリ | 6,656 KB |
最終ジャッジ日時 | 2024-09-16 07:48:24 |
合計ジャッジ時間 | 16,835 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 19 |
ソースコード
#![allow(non_snake_case)]#![allow(unused_imports)]#![allow(unused_macros)]#![allow(clippy::needless_range_loop)]#![allow(clippy::comparison_chain)]#![allow(clippy::nonminimal_bool)]#![allow(clippy::neg_multiply)]#![allow(dead_code)]use std::cmp::{min, Reverse};use std::collections::{vec_deque, BTreeMap, BTreeSet, BinaryHeap, VecDeque};const MOD: usize = 998244353;#[derive(Default)]struct Solver {}impl Solver {fn solve(&mut self) {input! {N: usize,M: usize,P: [usize; N]}let mut seg = SegmentTree::new(N + 1);let mut cnt = 0_usize;for &p in &P {cnt += seg.query(p, N + 1, 1, seg.offset + 1, 1) as usize;seg.update(p - 1, 1);}if cnt % 2 == 1 && M % 2 == 0 {println!("-1");} else {let target = M * ceil(cnt, M);if cnt % 2 == 1 {if target % 2 == 1 {println!("{}", target);} else {println!("{}", target + M);}} else {if M % 2 == 0 || target % 2 == 0 {println!("{}", target);} else {println!("{}", target + M);}}}}}fn ceil(a: usize, b: usize) -> usize {(a + b - 1) / b}#[derive(Debug, Clone)]struct SegmentTree {offset: usize,data: Vec<isize>,}impl SegmentTree {fn new(n: usize) -> Self {let mut offset = 1;while offset < n {offset *= 2;}let data = vec![0; offset * 2];SegmentTree { offset, data }}fn update(&mut self, pos: usize, x: isize) {let mut pos = pos + self.offset;self.data[pos] = x;while pos > 1 {pos /= 2;self.data[pos] = self.data[pos * 2] + self.data[pos * 2 + 1];}}// u: current cell number// (a, b], (l, r]fn query(&self, l: usize, r: usize, a: usize, b: usize, u: usize) -> isize {if r <= a || b <= l {return 0;}if l <= a && b <= r {return self.data[u];}let m = (a + b) / 2;self.query(l, r, a, m, u * 2) + self.query(l, r, m, b, u * 2 + 1)}}#[derive(Debug, Clone)]struct Comb {fact: Vec<ModInt>,fact_inverse: Vec<ModInt>,}impl Comb {fn new(n: usize) -> Self {let mut fact = vec![Mod::one(), Mod::one()];let mut fact_inverse = vec![Mod::one(), Mod::one()];let mut inverse = vec![Mod::zero(), Mod::one()];for i in 2..=n {fact.push(*fact.last().unwrap() * Mod::new(i));inverse.push((Mod::zero() - inverse[MOD % i]) * Mod::new(MOD / i));fact_inverse.push(*fact_inverse.last().unwrap() * *inverse.last().unwrap());}Comb { fact, fact_inverse }}fn nCr(&self, n: usize, r: usize) -> ModInt {self.fact[n] * self.fact_inverse[n - r] * self.fact_inverse[r]}fn nHr(&self, n: usize, r: usize) -> ModInt {self.nCr(n + r - 1, r)}}type Mod = ModInt;#[derive(Debug, Clone, Copy, Default)]struct ModInt {value: usize,}impl ModInt {fn new(n: usize) -> Self {ModInt { value: n % MOD }}fn zero() -> Self {ModInt { value: 0 }}fn one() -> Self {ModInt { value: 1 }}fn value(&self) -> usize {self.value}fn pow(&self, n: usize) -> Self {let mut p = *self;let mut ret = ModInt::one();let mut nn = n;while nn > 0 {if nn & 1 == 1 {ret *= p;}p *= p;nn >>= 1;}ret}fn inv(&self) -> Self {fn ext_gcd(a: usize, b: usize) -> (isize, isize, usize) {if a == 0 {return (0, 1, b);}let (x, y, g) = ext_gcd(b % a, a);(y - b as isize / a as isize * x, x, g)}ModInt::new((ext_gcd(self.value, MOD).0 + MOD as isize) as usize)}}impl std::ops::Add for ModInt {type Output = ModInt;fn add(self, other: Self) -> Self {ModInt::new(self.value + other.value)}}impl std::ops::Sub for ModInt {type Output = ModInt;fn sub(self, other: Self) -> Self {ModInt::new(MOD + self.value - other.value)}}impl std::ops::Mul for ModInt {type Output = ModInt;fn mul(self, other: Self) -> Self {ModInt::new(self.value * other.value)}}#[allow(clippy::suspicious_arithmetic_impl)]impl std::ops::Div for ModInt {type Output = ModInt;fn div(self, other: Self) -> Self {self * other.inv()}}impl std::ops::AddAssign for ModInt {fn add_assign(&mut self, other: Self) {*self = *self + other;}}impl std::ops::SubAssign for ModInt {fn sub_assign(&mut self, other: Self) {*self = *self - other;}}impl std::ops::MulAssign for ModInt {fn mul_assign(&mut self, other: Self) {*self = *self * other;}}impl std::ops::DivAssign for ModInt {fn div_assign(&mut self, other: Self) {*self = *self / other;}}trait Bound<T> {fn lower_bound(&self, x: &T) -> usize;fn upper_bound(&self, x: &T) -> usize;}impl<T: PartialOrd> Bound<T> for [T] {fn lower_bound(&self, x: &T) -> usize {let (mut low, mut high) = (0, self.len());while low + 1 < high {let mid = (low + high) / 2;if self[mid] < *x {low = mid;} else {high = mid;}}if self[low] < *x {low + 1} else {low}}fn upper_bound(&self, x: &T) -> usize {let (mut low, mut high) = (0, self.len());while low + 1 < high {let mid = (low + high) / 2;if self[mid] <= *x {low = mid;} else {high = mid;}}if self[low] <= *x {low + 1} else {low}}}#[macro_export]macro_rules! max {($x: expr) => ($x);($x: expr, $( $y: expr ),+) => {std::cmp::max($x, max!($( $y ),+))}}#[macro_export]macro_rules! min {($x: expr) => ($x);($x: expr, $( $y: expr ),+) => {std::cmp::min($x, min!($( $y ),+))}}fn main() {std::thread::Builder::new().stack_size(128 * 1024 * 1024).spawn(|| Solver::default().solve()).unwrap().join().unwrap();}#[macro_export]macro_rules! input {() => {};(mut $var:ident: $t:tt, $($rest:tt)*) => {let mut $var = __input_inner!($t);input!($($rest)*)};($var:ident: $t:tt, $($rest:tt)*) => {let $var = __input_inner!($t);input!($($rest)*)};(mut $var:ident: $t:tt) => {let mut $var = __input_inner!($t);};($var:ident: $t:tt) => {let $var = __input_inner!($t);};}#[macro_export]macro_rules! __input_inner {(($($t:tt),*)) => {($(__input_inner!($t)),*)};([$t:tt; $n:expr]) => {(0..$n).map(|_| __input_inner!($t)).collect::<Vec<_>>()};([$t:tt]) => {{let n = __input_inner!(usize);(0..n).map(|_| __input_inner!($t)).collect::<Vec<_>>()}};(chars) => {__input_inner!(String).chars().collect::<Vec<_>>()};(bytes) => {__input_inner!(String).into_bytes()};(usize1) => {__input_inner!(usize) - 1};($t:ty) => {$crate::read::<$t>()};}#[macro_export]macro_rules! println {() => {$crate::write(|w| {use std::io::Write;std::writeln!(w).unwrap()})};($($arg:tt)*) => {$crate::write(|w| {use std::io::Write;std::writeln!(w, $($arg)*).unwrap()})};}#[macro_export]macro_rules! print {($($arg:tt)*) => {$crate::write(|w| {use std::io::Write;std::write!(w, $($arg)*).unwrap()})};}#[macro_export]macro_rules! flush {() => {$crate::write(|w| {use std::io::Write;w.flush().unwrap()})};}pub fn read<T>() -> TwhereT: std::str::FromStr,T::Err: std::fmt::Debug,{use std::cell::RefCell;use std::io::*;thread_local! {pub static STDIN: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());}STDIN.with(|r| {let mut r = r.borrow_mut();let mut s = vec![];loop {let buf = r.fill_buf().unwrap();if buf.is_empty() {break;}if let Some(i) = buf.iter().position(u8::is_ascii_whitespace) {s.extend_from_slice(&buf[..i]);r.consume(i + 1);if !s.is_empty() {break;}} else {s.extend_from_slice(buf);let n = buf.len();r.consume(n);}}std::str::from_utf8(&s).unwrap().parse().unwrap()})}pub fn write<F>(f: F)whereF: FnOnce(&mut std::io::BufWriter<std::io::StdoutLock>),{use std::cell::RefCell;use std::io::*;thread_local! {pub static STDOUT: RefCell<BufWriter<StdoutLock<'static>>> =RefCell::new(BufWriter::new(stdout().lock()));}STDOUT.with(|w| f(&mut w.borrow_mut()))}