QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#659415 | #9486. Random Mex | ucup-team296# | AC ✓ | 1675ms | 526416kb | Rust | 49.0kb | 2024-10-19 20:05:34 | 2024-10-19 20:05:34 |
Judging History
answer
// https://contest.ucup.ac/contest/1812/problem/9486
pub mod solution {
//{"name":"K. Random Mex","group":"Universal Cup - The 3rd Universal Cup. Stage 13: Sendai","url":"https://contest.ucup.ac/contest/1812/problem/9486","interactive":false,"timeLimit":1000,"tests":[{"input":"4\n3 2\n1 1\n20 23\n8000 8000\n","output":"374341634\n1\n111675632\n994279778\n"}],"testType":"single","input":{"type":"stdin","fileName":null,"pattern":null},"output":{"type":"stdout","fileName":null,"pattern":null},"languages":{"java":{"taskClass":"KRandomMex"}}}
use crate::algo_lib::collections::md_arr::arr2d::Arr2d;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
// use algo_lib::misc::extensions::do_with::DoWith;
use crate::algo_lib::collections::slice_ext::indices::Indices;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
use crate::algo_lib::misc::value::Value;
use crate::algo_lib::numbers::mod_int::ModIntF;
use crate::algo_lib::numbers::mod_int::ValF;
use crate::algo_lib::numbers::mod_utils::Combinations;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use crate::algo_lib::numbers::number_ext::Power;
use std::collections::HashMap;
use std::mem::transmute;
// use algo_lib::numbers::prime_fft::PrimeFFT;
type PreCalc = ();
fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
let t = input.read_size();
let queries = input.read_size_pair_vec(t);
type Mod = ModIntF;
let cc = Combinations::<Mod>::new(8001);
/*let at = vec![Vec::new(); 8001].do_with(|at| {
for (i, (n, m)) in queries.into_iter().enumerate() {
at[m].push((n, i));
}
});
let mut ans = vec![Mod::zero(); t];
let mut a = vec![Mod::zero(); 8001];
let mut b = vec![Mod::zero(); 8001];
let mut c = vec![Mod::zero(); 8001];
let mut fft = PrimeFFT::new();
let mut d = Arr2d::new(20, 20, 0);
for m in 1..=20 {
// if m % 500 == 0 {
// eprintln!("m = {}", m);
// }
let mut mult = Mod::one();
let mut by = Mod::from_index(m - 1) / Mod::from_index(m);
for i in 0..=8000 {
a[i] = (c[i] + Mod::one()) * mult * cc.inv_fact(i);
mult *= by;
}
mult = Mod::one();
by = Mod::one() - by;
for i in 1..=8000 {
mult *= by;
b[i] = mult * cc.inv_fact(i);
}
fft.multiply_res(&a, &b, &mut c);
for i in 0..=8000 {
c[i] = c[i] * cc.fact(i);
}
for i in 0..20 {
d[(m - 1, i)] = (c[i] * Mod::from_index(m).power(i)).val();
}
for (n, i) in at[m].iter() {
ans[*i] = c[*n];
}
}
for i in 0..20 {
for j in 0..20 {
eprint!("{} ", d[(j, i)]);
}
eprintln!();
}*/
let mut a = Arr2d::new(8001, 8001, Mod::zero());
for m in 1..=8000 {
a[(m, 0)] = Mod::from_index(m);
let im = Mod::from_index(m).inv().unwrap();
for q in 1..m {
a[(m, q)] = Mod::from_index(m - q) * im * (Mod::one() + a[(m - 1, q)]);
}
}
for m in 1..=8000 {
for q in 0..=m {
a[(m, q)] *= cc.c(m, q);
}
}
let mut b = Arr2d::new(8001, 8001, Mod::zero());
b[(0, 0)] = Mod::one();
for n in 1..=8000 {
for p in 1..=n {
b[(n, p)] = Mod::from_index(p) * (b[(n - 1, p - 1)] + b[(n - 1, p)]);
}
}
for n in 0..=8000 {
b[n].reverse();
}
// let mut c = Arr2d::new(8001, 8001, Mod::zero());
// for i in 1..=8000 {
// c[(i, 0)] = Mod::one();
// let by = Mod::from_index(i).inv().unwrap();
// for j in 1..=800 {
// c[(i, j)] = c[(i, j - 1)] * by;
// }
// }
let mut cache = HashMap::<(usize, usize), Mod>::new();
let a: Arr2d<i32> = unsafe { transmute(a) };
let b: Arr2d<i32> = unsafe { transmute(b) };
fn multiply(a: &[i32], b: &[i32]) -> i128 {
let mut res = 0;
for i in a.indices() {
res += ((a[i] as i64) * (b[i] as i64)) as i128;
}
res
}
const THRESHOLD: u64 = 998_244_353u64 * 17_000_000_000;
for (n, m) in queries {
if let Some(val) = cache.get(&(n, m)) {
out.print_line(*val);
continue;
}
let mut res = 0;
let mut add = 0;
// let mut done = 0;
let aa = &a[m];
let bb = &b[n][8000 - m..];
let res = multiply(&aa[m.max(n) - n..m], &bb[m.max(n) - n..m]);
// for z in m.max(n) - n..m {
// eprintln!(
// "{} {} {} {:?} {:?} {:?}",
// n,
// m,
// z,
// a[(m, z)],
// b[(n, m - z)],
// c[(m - z, n)]
// );
// res += ((a[(m, z)].val() as u64) * (b[(n, m - z)].val() as u64));
// if res >= THRESHOLD {
// res -= THRESHOLD;
// }
// let xx;
// (res, xx) =
// res.overflowing_add((a[(m, z)].val() as i64) * (b[(n, m - z)].val() as i64));
// add += xx as i32;
// res += ((aa[z] as i64) * (bb[z] as i64)) as i128;
// done += 1;
// if done == 18 {
// res %= ValF::val() as u64;
// done = 0;
// }
// }
// let mut res = Mod::new((res % ValF::val() as u64) as i32);
let mut res =
Mod::new(((res as i128 + ((add as i128) << 64)) % ValF::val() as i128) as i32);
res /= Mod::from_index(m).power(n);
out.print_line(res);
cache.insert((n, m), res);
// return;
}
}
#[cfg(test)]
mod test {
use crate::algo_lib::collections::md_arr::arr2d::Arr2d;
use crate::algo_lib::numbers::mod_int::ModIntF;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
#[test]
fn test() {
type Mod = ModIntF;
let mut b = Arr2d::new(20, 20, Mod::zero());
}
}
pub static TEST_TYPE: TestType = TestType::Single;
pub static TASK_TYPE: TaskType = TaskType::Classic;
pub(crate) fn run(mut input: Input, mut output: Output) -> bool {
let mut pre_calc = ();
match TEST_TYPE {
TestType::Single => solve(&mut input, &mut output, 1, &mut pre_calc),
TestType::MultiNumber => {
let t = input.read();
for i in 1..=t {
solve(&mut input, &mut output, i, &mut pre_calc);
}
}
TestType::MultiEof => {
let mut i = 1;
while input.peek().is_some() {
solve(&mut input, &mut output, i, &mut pre_calc);
i += 1;
}
}
}
output.flush();
match TASK_TYPE {
TaskType::Classic => input.is_empty(),
TaskType::Interactive => true,
}
}
}
pub mod algo_lib {
pub mod collections {
pub mod md_arr {
pub mod arr2d {
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::input::Readable;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::io::output::Writable;
use std::mem::MaybeUninit;
use std::ops::Index;
use std::ops::IndexMut;
use std::ops::Range;
use std::slice::Iter;
use std::vec::IntoIter;
#[derive(Clone, Eq, PartialEq, Default)]
pub struct Arr2d<T> {
d1: usize,
d2: usize,
data: Vec<T>,
}
impl<T: Clone> Arr2d<T> {
pub fn new(d1: usize, d2: usize, value: T) -> Self {
Self {
d1,
d2,
data: vec![value; d1 * d2],
}
}
}
impl<T> Arr2d<T> {
pub fn generate<F>(d1: usize, d2: usize, mut gen: F) -> Self
where
F: FnMut(usize, usize) -> T,
{
let mut data = Vec::with_capacity(d1 * d2);
for i in 0usize..d1 {
for j in 0usize..d2 {
data.push(gen(i, j));
}
}
Self { d1, d2, data }
}
pub fn d1(&self) -> usize {
self.d1
}
pub fn d2(&self) -> usize {
self.d2
}
pub fn iter(&self) -> Iter<'_, T> {
self.data.iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.data.iter_mut()
}
pub fn row(&self, row: usize) -> impl Iterator<Item = &T> {
assert!(row < self.d1);
self.data.iter().skip(row * self.d2).take(self.d2)
}
pub fn row_mut(&mut self, row: usize) -> impl Iterator<Item = &mut T> {
assert!(row < self.d1);
self.data.iter_mut().skip(row * self.d2).take(self.d2)
}
pub fn column(&self, col: usize) -> impl Iterator<Item = &T> {
assert!(col < self.d2);
self.data.iter().skip(col).step_by(self.d2)
}
pub fn column_mut(&mut self, col: usize) -> impl Iterator<Item = &mut T> {
assert!(col < self.d2);
self.data.iter_mut().skip(col).step_by(self.d2)
}
pub fn swap(&mut self, r1: usize, c1: usize, r2: usize, c2: usize) {
assert!(r1 < self.d1);
assert!(r2 < self.d1);
assert!(c1 < self.d2);
assert!(c2 < self.d2);
self.data.swap(r1 * self.d2 + c1, r2 * self.d2 + c2);
}
pub fn rows(&self) -> Range<usize> {
0..self.d1
}
pub fn cols(&self) -> Range<usize> {
0..self.d2
}
pub fn swap_rows(&mut self, r1: usize, r2: usize) {
assert!(r1 < self.d1);
assert!(r2 < self.d1);
if r1 == r2 {
return;
}
let (r1, r2) = (r1.min(r2), r1.max(r2));
let (head, tail) = self.data.split_at_mut(r2 * self.d2);
head[r1 * self.d2..(r1 + 1) * self.d2].swap_with_slice(&mut tail[..self.d2]);
}
pub fn rotate_clockwise(self) -> Self {
unsafe {
let d1 = self.d1;
let d2 = self.d2;
let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
(*res.as_mut_ptr()).set_len(d1 * d2);
for (id, element) in self.into_iter().enumerate() {
let (i, j) = (id / d2, id % d2);
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add(j * d1 + d1 - i - 1).write(element);
}
Self {
d1: d2,
d2: d1,
data: res.assume_init(),
}
}
}
pub fn rotate_counterclockwise(self) -> Self {
unsafe {
let d1 = self.d1;
let d2 = self.d2;
let mut res = MaybeUninit::new(Vec::with_capacity(d1 * d2));
(*res.as_mut_ptr()).set_len(d1 * d2);
for (id, element) in self.into_iter().enumerate() {
let (i, j) = (id / d2, id % d2);
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add((d2 - j - 1) * d1 + i).write(element);
}
Self {
d1: d2,
d2: d1,
data: res.assume_init(),
}
}
}
}
impl<T: Clone> Arr2d<T> {
pub fn fill(&mut self, elem: T) {
self.data.legacy_fill(elem);
}
pub fn transpose(&self) -> Self {
Self::generate(self.d2, self.d1, |i, j| self[(j, i)].clone())
}
}
impl<T> Index<(usize, usize)> for Arr2d<T> {
type Output = T;
fn index(&self, (row, col): (usize, usize)) -> &Self::Output {
assert!(row < self.d1);
assert!(col < self.d2);
&self.data[self.d2 * row + col]
}
}
impl<T> Index<usize> for Arr2d<T> {
type Output = [T];
fn index(&self, index: usize) -> &Self::Output {
&self.data[self.d2 * index..self.d2 * (index + 1)]
}
}
impl<T> IndexMut<(usize, usize)> for Arr2d<T> {
fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut T {
assert!(row < self.d1);
assert!(col < self.d2);
&mut self.data[self.d2 * row + col]
}
}
impl<T> IndexMut<usize> for Arr2d<T> {
fn index_mut(&mut self, index: usize) -> &mut [T] {
&mut self.data[self.d2 * index..self.d2 * (index + 1)]
}
}
impl<T> AsRef<Vec<T>> for Arr2d<T> {
fn as_ref(&self) -> &Vec<T> {
&self.data
}
}
impl<T> AsMut<Vec<T>> for Arr2d<T> {
fn as_mut(&mut self) -> &mut Vec<T> {
&mut self.data
}
}
impl<T: Writable> Writable for Arr2d<T> {
fn write(&self, output: &mut Output) {
let mut at = 0usize;
for i in 0usize..self.d1 {
if i != 0 {
output.put(b'\n');
}
for j in 0usize..self.d2 {
if j != 0 {
output.put(b' ');
}
self.data[at].write(output);
at += 1;
}
}
}
}
impl<T> IntoIterator for Arr2d<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
impl<'a, T> IntoIterator for &'a Arr2d<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub trait Arr2dRead {
fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T>;
fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32>;
fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64>;
fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize>;
fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8>;
}
impl Arr2dRead for Input<'_> {
fn read_table<T: Readable>(&mut self, d1: usize, d2: usize) -> Arr2d<T> {
Arr2d::generate(d1, d2, |_, _| self.read())
}
fn read_int_table(&mut self, d1: usize, d2: usize) -> Arr2d<i32> {
self.read_table(d1, d2)
}
fn read_long_table(&mut self, d1: usize, d2: usize) -> Arr2d<i64> {
self.read_table(d1, d2)
}
fn read_size_table(&mut self, d1: usize, d2: usize) -> Arr2d<usize> {
self.read_table(d1, d2)
}
fn read_char_table(&mut self, d1: usize, d2: usize) -> Arr2d<u8> {
self.read_table(d1, d2)
}
}
pub trait Arr2dCharWrite {
fn print_table(&mut self, table: &Arr2d<u8>);
}
impl Arr2dCharWrite for Output<'_> {
fn print_table(&mut self, table: &Arr2d<u8>) {
let mut at = 0usize;
for _ in 0..table.d1 {
for _ in 0..table.d2 {
self.put(table.data[at]);
at += 1;
}
self.put(b'\n');
}
self.maybe_flush();
}
}
impl<T: Readable> Readable for Arr2d<T> {
fn read(input: &mut Input) -> Self {
let d1 = input.read();
let d2 = input.read();
input.read_table(d1, d2)
}
}
}
}
pub mod slice_ext {
pub mod indices {
use std::ops::Range;
pub trait Indices {
fn indices(&self) -> Range<usize>;
}
impl<T> Indices for [T] {
fn indices(&self) -> Range<usize> {
0..self.len()
}
}
}
pub mod legacy_fill {
// 1.50
pub trait LegacyFill<T> {
fn legacy_fill(&mut self, val: T);
}
impl<T: Clone> LegacyFill<T> for [T] {
fn legacy_fill(&mut self, val: T) {
for el in self.iter_mut() {
*el = val.clone();
}
}
}
}
}
pub mod vec_ext {
pub mod default {
pub fn default_vec<T: Default>(len: usize) -> Vec<T> {
let mut v = Vec::with_capacity(len);
for _ in 0..len {
v.push(T::default());
}
v
}
}
}
}
pub mod io {
pub mod input {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::io::Read;
pub struct Input<'s> {
input: &'s mut (dyn Read + Send),
buf: Vec<u8>,
at: usize,
buf_read: usize,
}
macro_rules! read_impl {
($t: ty, $read_name: ident, $read_vec_name: ident) => {
pub fn $read_name(&mut self) -> $t {
self.read()
}
pub fn $read_vec_name(&mut self, len: usize) -> Vec<$t> {
self.read_vec(len)
}
};
($t: ty, $read_name: ident, $read_vec_name: ident, $read_pair_vec_name: ident) => {
read_impl!($t, $read_name, $read_vec_name);
pub fn $read_pair_vec_name(&mut self, len: usize) -> Vec<($t, $t)> {
self.read_vec(len)
}
};
}
impl<'s> Input<'s> {
const DEFAULT_BUF_SIZE: usize = 4096;
pub fn new(input: &'s mut (dyn Read + Send)) -> Self {
Self {
input,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
buf_read: 0,
}
}
pub fn new_with_size(input: &'s mut (dyn Read + Send), buf_size: usize) -> Self {
Self {
input,
buf: default_vec(buf_size),
at: 0,
buf_read: 0,
}
}
pub fn get(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
self.at += 1;
if res == b'\r' {
if self.refill_buffer() && self.buf[self.at] == b'\n' {
self.at += 1;
}
return Some(b'\n');
}
Some(res)
} else {
None
}
}
pub fn peek(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
Some(if res == b'\r' { b'\n' } else { res })
} else {
None
}
}
pub fn skip_whitespace(&mut self) {
while let Some(b) = self.peek() {
if !b.is_ascii_whitespace() {
return;
}
self.get();
}
}
pub fn next_token(&mut self) -> Option<Vec<u8>> {
self.skip_whitespace();
let mut res = Vec::new();
while let Some(c) = self.get() {
if c.is_ascii_whitespace() {
break;
}
res.push(c);
}
if res.is_empty() {
None
} else {
Some(res)
}
}
//noinspection RsSelfConvention
pub fn is_exhausted(&mut self) -> bool {
self.peek().is_none()
}
//noinspection RsSelfConvention
pub fn is_empty(&mut self) -> bool {
self.skip_whitespace();
self.is_exhausted()
}
pub fn read<T: Readable>(&mut self) -> T {
T::read(self)
}
pub fn read_vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
let mut res = Vec::with_capacity(size);
for _ in 0..size {
res.push(self.read());
}
res
}
pub fn read_char(&mut self) -> u8 {
self.skip_whitespace();
self.get().unwrap()
}
read_impl!(u32, read_unsigned, read_unsigned_vec);
read_impl!(u64, read_u64, read_u64_vec);
read_impl!(usize, read_size, read_size_vec, read_size_pair_vec);
read_impl!(i32, read_int, read_int_vec, read_int_pair_vec);
read_impl!(i64, read_long, read_long_vec, read_long_pair_vec);
read_impl!(i128, read_i128, read_i128_vec);
fn refill_buffer(&mut self) -> bool {
if self.at == self.buf_read {
self.at = 0;
self.buf_read = self.input.read(&mut self.buf).unwrap();
self.buf_read != 0
} else {
true
}
}
}
pub trait Readable {
fn read(input: &mut Input) -> Self;
}
impl Readable for u8 {
fn read(input: &mut Input) -> Self {
input.read_char()
}
}
impl<T: Readable> Readable for Vec<T> {
fn read(input: &mut Input) -> Self {
let size = input.read();
input.read_vec(size)
}
}
macro_rules! read_integer {
($($t:ident)+) => {$(
impl Readable for $t {
fn read(input: &mut Input) -> Self {
input.skip_whitespace();
let mut c = input.get().unwrap();
let sgn = match c {
b'-' => {
c = input.get().unwrap();
true
}
b'+' => {
c = input.get().unwrap();
false
}
_ => false,
};
let mut res = 0;
loop {
assert!(c.is_ascii_digit());
res *= 10;
let d = (c - b'0') as $t;
if sgn {
res -= d;
} else {
res += d;
}
match input.get() {
None => break,
Some(ch) => {
if ch.is_ascii_whitespace() {
break;
} else {
c = ch;
}
}
}
}
res
}
}
)+};
}
read_integer!(i8 i16 i32 i64 i128 isize u16 u32 u64 u128 usize);
macro_rules! tuple_readable {
($($name:ident)+) => {
impl<$($name: Readable), +> Readable for ($($name,)+) {
fn read(input: &mut Input) -> Self {
($($name::read(input),)+)
}
}
}
}
tuple_readable! {T}
tuple_readable! {T U}
tuple_readable! {T U V}
tuple_readable! {T U V X}
tuple_readable! {T U V X Y}
tuple_readable! {T U V X Y Z}
tuple_readable! {T U V X Y Z A}
tuple_readable! {T U V X Y Z A B}
tuple_readable! {T U V X Y Z A B C}
tuple_readable! {T U V X Y Z A B C D}
tuple_readable! {T U V X Y Z A B C D E}
tuple_readable! {T U V X Y Z A B C D E F}
impl Read for Input<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.at == self.buf_read {
self.input.read(buf)
} else {
let mut i = 0;
while i < buf.len() && self.at < self.buf_read {
buf[i] = self.buf[self.at];
i += 1;
self.at += 1;
}
Ok(i)
}
}
}
}
pub mod output {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::cmp::Reverse;
use std::io::stderr;
use std::io::Stderr;
use std::io::Write;
#[derive(Copy, Clone)]
pub enum BoolOutput {
YesNo,
YesNoCaps,
PossibleImpossible,
Custom(&'static str, &'static str),
}
impl BoolOutput {
pub fn output(&self, output: &mut Output, val: bool) {
(if val { self.yes() } else { self.no() }).write(output);
}
fn yes(&self) -> &str {
match self {
BoolOutput::YesNo => "Yes",
BoolOutput::YesNoCaps => "YES",
BoolOutput::PossibleImpossible => "Possible",
BoolOutput::Custom(yes, _) => yes,
}
}
fn no(&self) -> &str {
match self {
BoolOutput::YesNo => "No",
BoolOutput::YesNoCaps => "NO",
BoolOutput::PossibleImpossible => "Impossible",
BoolOutput::Custom(_, no) => no,
}
}
}
pub struct Output<'s> {
output: &'s mut dyn Write,
buf: Vec<u8>,
at: usize,
auto_flush: bool,
bool_output: BoolOutput,
}
impl<'s> Output<'s> {
const DEFAULT_BUF_SIZE: usize = 4096;
pub fn new(output: &'s mut dyn Write) -> Self {
Self {
output,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
auto_flush: false,
bool_output: BoolOutput::YesNoCaps,
}
}
pub fn new_with_auto_flush(output: &'s mut dyn Write) -> Self {
Self {
output,
buf: default_vec(Self::DEFAULT_BUF_SIZE),
at: 0,
auto_flush: true,
bool_output: BoolOutput::YesNoCaps,
}
}
pub fn flush(&mut self) {
if self.at != 0 {
self.output.write_all(&self.buf[..self.at]).unwrap();
self.output.flush().unwrap();
self.at = 0;
}
}
pub fn print<T: Writable>(&mut self, s: T) {
s.write(self);
self.maybe_flush();
}
pub fn print_line<T: Writable>(&mut self, s: T) {
self.print(s);
self.put(b'\n');
self.maybe_flush();
}
pub fn put(&mut self, b: u8) {
self.buf[self.at] = b;
self.at += 1;
if self.at == self.buf.len() {
self.flush();
}
}
pub fn maybe_flush(&mut self) {
if self.auto_flush {
self.flush();
}
}
pub fn print_per_line<T: Writable>(&mut self, arg: &[T]) {
self.print_per_line_iter(arg.iter());
}
pub fn print_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
let mut first = true;
for e in iter {
if first {
first = false;
} else {
self.put(b' ');
}
e.write(self);
}
}
pub fn print_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
self.print_iter(iter);
self.put(b'\n');
}
pub fn print_per_line_iter<T: Writable, I: Iterator<Item = T>>(&mut self, iter: I) {
for e in iter {
e.write(self);
self.put(b'\n');
}
}
pub fn set_bool_output(&mut self, bool_output: BoolOutput) {
self.bool_output = bool_output;
}
}
impl Write for Output<'_> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let mut start = 0usize;
let mut rem = buf.len();
while rem > 0 {
let len = (self.buf.len() - self.at).min(rem);
self.buf[self.at..self.at + len].copy_from_slice(&buf[start..start + len]);
self.at += len;
if self.at == self.buf.len() {
self.flush();
}
start += len;
rem -= len;
}
self.maybe_flush();
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
self.flush();
Ok(())
}
}
pub trait Writable {
fn write(&self, output: &mut Output);
}
impl Writable for &str {
fn write(&self, output: &mut Output) {
output.write_all(self.as_bytes()).unwrap();
}
}
impl Writable for String {
fn write(&self, output: &mut Output) {
output.write_all(self.as_bytes()).unwrap();
}
}
impl Writable for char {
fn write(&self, output: &mut Output) {
output.put(*self as u8);
}
}
impl Writable for u8 {
fn write(&self, output: &mut Output) {
output.put(*self);
}
}
impl<T: Writable> Writable for [T] {
fn write(&self, output: &mut Output) {
output.print_iter(self.iter());
}
}
impl<T: Writable, const N: usize> Writable for [T; N] {
fn write(&self, output: &mut Output) {
output.print_iter(self.iter());
}
}
impl<T: Writable + ?Sized> Writable for &T {
fn write(&self, output: &mut Output) {
T::write(self, output)
}
}
impl<T: Writable> Writable for Vec<T> {
fn write(&self, output: &mut Output) {
self.as_slice().write(output);
}
}
impl Writable for () {
fn write(&self, _output: &mut Output) {}
}
macro_rules! write_to_string {
($($t:ident)+) => {$(
impl Writable for $t {
fn write(&self, output: &mut Output) {
self.to_string().write(output);
}
}
)+};
}
write_to_string!(u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
macro_rules! tuple_writable {
($name0:ident $($name:ident: $id:tt )*) => {
impl<$name0: Writable, $($name: Writable,)*> Writable for ($name0, $($name,)*) {
fn write(&self, out: &mut Output) {
self.0.write(out);
$(
out.put(b' ');
self.$id.write(out);
)*
}
}
}
}
tuple_writable! {T}
tuple_writable! {T U:1}
tuple_writable! {T U:1 V:2}
tuple_writable! {T U:1 V:2 X:3}
tuple_writable! {T U:1 V:2 X:3 Y:4}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6 B:7}
tuple_writable! {T U:1 V:2 X:3 Y:4 Z:5 A:6 B:7 C:8}
impl<T: Writable> Writable for Option<T> {
fn write(&self, output: &mut Output) {
match self {
None => (-1).write(output),
Some(t) => t.write(output),
}
}
}
impl Writable for bool {
fn write(&self, output: &mut Output) {
let bool_output = output.bool_output;
bool_output.output(output, *self)
}
}
impl<T: Writable> Writable for Reverse<T> {
fn write(&self, output: &mut Output) {
self.0.write(output);
}
}
static mut ERR: Option<Stderr> = None;
pub fn err() -> Output<'static> {
unsafe {
if ERR.is_none() {
ERR = Some(stderr());
}
Output::new_with_auto_flush(ERR.as_mut().unwrap())
}
}
}
}
pub mod misc {
pub mod test_type {
pub enum TestType {
Single,
MultiNumber,
MultiEof,
}
pub enum TaskType {
Classic,
Interactive,
}
}
pub mod value {
use std::hash::Hash;
pub trait Value<T>: Copy + Eq + Hash {
fn val() -> T;
}
pub trait ConstValue<T>: Value<T> {
const VAL: T;
}
impl<T, V: ConstValue<T>> Value<T> for V {
fn val() -> T {
Self::VAL
}
}
#[macro_export]
macro_rules! value {
($name: ident: $t: ty = $val: expr) => {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Default)]
pub struct $name {}
impl $crate::algo_lib::misc::value::ConstValue<$t> for $name {
const VAL: $t = $val;
}
};
}
pub trait DynamicValue<T>: Value<T> {
//noinspection RsSelfConvention
fn set_val(t: T);
}
#[macro_export]
macro_rules! dynamic_value {
($name: ident: $t: ty, $val: ident) => {
static mut $val: Option<$t> = None;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Default)]
struct $name {}
impl $crate::algo_lib::misc::value::DynamicValue<$t> for $name {
fn set_val(t: $t) {
unsafe {
$val = Some(t);
}
}
}
impl $crate::algo_lib::misc::value::Value<$t> for $name {
fn val() -> $t {
unsafe { $val.unwrap() }
}
}
};
($name: ident: $t: ty) => {
dynamic_value!($name: $t, VAL);
};
($name: ident: $t: ty = $val: expr) => {
dynamic_value!($name: $t);
$name::set_val($val);
};
($name: ident: $t: ty = $val: expr, $val_static: ident) => {
dynamic_value!($name: $t, $val_static);
$name::set_val($val);
};
}
}
pub mod when {
#[macro_export]
macro_rules! when {
{$($cond: expr => $then: expr,)*} => {
match () {
$(_ if $cond => $then,)*
_ => unreachable!(),
}
};
{$($cond: expr => $then: expr,)* else $(=>)? $else: expr$(,)?} => {
match () {
$(_ if $cond => $then,)*
_ => $else,
}
};
}
}
}
pub mod numbers {
pub mod gcd {
use crate::algo_lib::numbers::num_traits::algebra::IntegerMultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRingWithSub;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::SemiRingWithSub;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::wideable::Wideable;
use std::mem::swap;
pub fn extended_gcd<T: IntegerSemiRingWithSub + Wideable + Copy>(a: T, b: T) -> (T, T::W, T::W)
where
T::W: Copy + SemiRingWithSub,
{
if a == T::zero() {
(b, T::W::zero(), T::W::one())
} else {
let (d, y, mut x) = extended_gcd(b % a, a);
x -= T::W::from(b / a) * y;
(d, x, y)
}
}
pub fn gcd<T: Copy + Zero + IntegerMultiplicationMonoid>(mut a: T, mut b: T) -> T {
while b != T::zero() {
a %= b;
swap(&mut a, &mut b);
}
a
}
pub fn lcm<T: Copy + Zero + IntegerMultiplicationMonoid>(a: T, b: T) -> T {
(a / gcd(a, b)) * b
}
}
pub mod mod_int {
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::input::Readable;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::io::output::Writable;
use crate::algo_lib::misc::value::Value;
use crate::algo_lib::numbers::gcd::extended_gcd;
use crate::algo_lib::numbers::num_traits::algebra::Field;
use crate::algo_lib::numbers::num_traits::algebra::IntegerRing;
use crate::algo_lib::numbers::num_traits::algebra::One;
use crate::algo_lib::numbers::num_traits::algebra::Ring;
use crate::algo_lib::numbers::num_traits::algebra::Zero;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use crate::algo_lib::numbers::num_traits::wideable::Wideable;
use crate::value;
use crate::when;
use std::collections::HashMap;
use std::fmt::Display;
use std::fmt::Formatter;
use std::hash::Hash;
use std::marker::PhantomData;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;
use std::ops::Sub;
use std::ops::SubAssign;
pub trait BaseModInt: Field + Copy {
type W: IntegerRing + Copy + From<Self::T>;
type T: IntegerRing + Ord + Copy + Wideable<W = Self::W>;
fn from(v: Self::T) -> Self;
fn module() -> Self::T;
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Default)]
pub struct ModInt<T, V: Value<T>> {
n: T,
phantom: PhantomData<V>,
}
impl<T: Copy, V: Value<T>> ModInt<T, V> {
pub fn val(&self) -> T {
self.n
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> ModInt<T, V> {
unsafe fn unchecked_new(n: T) -> Self {
debug_assert!(n >= T::zero() && n < V::val());
Self {
n,
phantom: Default::default(),
}
}
unsafe fn maybe_subtract_mod(mut n: T) -> T {
debug_assert!(n < V::val() + V::val() && n >= T::zero());
if n >= V::val() {
n -= V::val();
}
n
}
}
impl<T: IntegerRing + Ord + Copy, V: Value<T>> ModInt<T, V> {
pub fn new(n: T) -> Self {
unsafe { Self::unchecked_new(Self::maybe_subtract_mod(n % (V::val()) + V::val())) }
}
}
impl<T: Copy + IntegerRing + Ord + Wideable + Hash, V: Value<T>> ModInt<T, V>
where
T::W: Copy + IntegerRing,
{
pub fn log(&self, alpha: Self) -> T {
let mut base = HashMap::new();
let mut exp = T::zero();
let mut pow = Self::one();
let mut inv = *self;
let alpha_inv = alpha.inv().unwrap();
while exp * exp < Self::module() {
if inv == Self::one() {
return exp;
}
base.insert(inv, exp);
exp += T::one();
pow *= alpha;
inv *= alpha_inv;
}
let step = pow;
let mut i = T::one();
loop {
if let Some(b) = base.get(&pow) {
break exp * i + *b;
}
pow *= step;
i += T::one();
}
}
}
impl<T: Wideable + Ring + Ord + Copy, V: Value<T>> ModInt<T, V>
where
T::W: IntegerRing,
{
pub fn new_from_wide(n: T::W) -> Self {
unsafe {
Self::unchecked_new(Self::maybe_subtract_mod(
T::downcast(n % V::val().into()) + V::val(),
))
}
}
}
impl<T: Copy + IntegerRing + Ord + Wideable, V: Value<T>> Invertible for ModInt<T, V>
where
T::W: Copy + IntegerRing,
{
type Output = Self;
fn inv(&self) -> Option<Self> {
let (g, x, _) = extended_gcd(self.n, V::val());
if g != T::one() {
None
} else {
Some(Self::new_from_wide(x))
}
}
}
impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> BaseModInt for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
type W = T::W;
type T = T;
fn from(v: Self::T) -> Self {
Self::new(v)
}
fn module() -> T {
V::val()
}
}
impl<T: IntegerRing + Ord + Copy, V: Value<T>> From<T> for ModInt<T, V> {
fn from(n: T) -> Self {
Self::new(n)
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> AddAssign for ModInt<T, V> {
fn add_assign(&mut self, rhs: Self) {
self.n = unsafe { Self::maybe_subtract_mod(self.n + rhs.n) };
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> Add for ModInt<T, V> {
type Output = Self;
fn add(mut self, rhs: Self) -> Self::Output {
self += rhs;
self
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> SubAssign for ModInt<T, V> {
fn sub_assign(&mut self, rhs: Self) {
self.n = unsafe { Self::maybe_subtract_mod(self.n + V::val() - rhs.n) };
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> Sub for ModInt<T, V> {
type Output = Self;
fn sub(mut self, rhs: Self) -> Self::Output {
self -= rhs;
self
}
}
impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> MulAssign for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
fn mul_assign(&mut self, rhs: Self) {
self.n = T::downcast(T::W::from(self.n) * T::W::from(rhs.n) % T::W::from(V::val()));
}
}
impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> Mul for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
type Output = Self;
fn mul(mut self, rhs: Self) -> Self::Output {
self *= rhs;
self
}
}
impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> DivAssign for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
#[allow(clippy::suspicious_op_assign_impl)]
fn div_assign(&mut self, rhs: Self) {
*self *= rhs.inv().unwrap();
}
}
impl<T: IntegerRing + Ord + Copy + Wideable, V: Value<T>> Div for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
type Output = Self;
fn div(mut self, rhs: Self) -> Self::Output {
self /= rhs;
self
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> Neg for ModInt<T, V> {
type Output = Self;
fn neg(mut self) -> Self::Output {
self.n = unsafe { Self::maybe_subtract_mod(V::val() - self.n) };
self
}
}
impl<T: Display, V: Value<T>> Display for ModInt<T, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
<T as Display>::fmt(&self.n, f)
}
}
impl<T: IntegerRing + Ord + Copy + Readable, V: Value<T>> Readable for ModInt<T, V> {
fn read(input: &mut Input) -> Self {
Self::new(T::read(input))
}
}
impl<T: Writable, V: Value<T>> Writable for ModInt<T, V> {
fn write(&self, output: &mut Output) {
self.n.write(output);
}
}
impl<T: Ring + Ord + Copy, V: Value<T>> Zero for ModInt<T, V> {
fn zero() -> Self {
unsafe { Self::unchecked_new(T::zero()) }
}
}
impl<T: IntegerRing + Ord + Copy, V: Value<T>> One for ModInt<T, V> {
fn one() -> Self {
Self::new(T::one())
}
}
impl<T, V: Value<T>> Wideable for ModInt<T, V> {
type W = Self;
fn downcast(w: Self::W) -> Self {
w
}
}
impl<T: IntegerRing + Ord + Copy + Wideable + Display + AsIndex, V: Value<T>> std::fmt::Debug
for ModInt<T, V>
where
T::W: IntegerRing + Copy,
{
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
let max = T::from_index(100);
when! {
self.n <= max => write!(f, "{}", self.n),
self.n >= V::val() - max => write!(f, "{}", self.n - V::val()),
else => {
let mut denominator = T::one();
while denominator < max {
let mut num = T::one();
while num < max {
if Self::new(num) / Self::new(denominator) == *self {
return write!(f, "{}/{}", num, denominator);
}
if -Self::new(num) / Self::new(denominator) == *self {
return write!(f, "-{}/{}", num, denominator);
}
num += T::one();
}
denominator += T::one();
}
write!(f, "(?? {} ??)", self.n)
},
}
}
}
impl<T: IntegerRing + Ord + Copy + AsIndex, V: Value<T>> AsIndex for ModInt<T, V> {
fn from_index(idx: usize) -> Self {
Self::new(T::from_index(idx))
}
fn to_index(self) -> usize {
self.n.to_index()
}
}
value!(Val7: i32 = 1_000_000_007);
pub type ModInt7 = ModInt<i32, Val7>;
value!(Val9: i32 = 1_000_000_009);
pub type ModInt9 = ModInt<i32, Val9>;
value!(ValF: i32 = 998_244_353);
pub type ModIntF = ModInt<i32, ValF>;
}
pub mod mod_utils {
use crate::algo_lib::numbers::mod_int::BaseModInt;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_utils::factorial;
use crate::algo_lib::numbers::num_utils::factorials;
pub fn inverses<M: BaseModInt>(len: usize) -> Vec<M>
where
M::T: AsIndex,
{
let mut res = Vec::new();
if len > 0 {
res.push(M::zero());
}
if len > 1 {
res.push(M::one());
}
while res.len() < len {
res.push(
res[M::module().to_index() % res.len()]
* (M::from(M::module() / (M::T::from_index(res.len()))).neg()),
);
}
res
}
pub fn inverse_factorials<M: BaseModInt>(len: usize) -> Vec<M>
where
M::T: AsIndex,
{
let mut res = inverses(len);
if len > 0 {
res[0] = M::one();
}
for i in 1..len {
let last = res[i - 1];
res[i] *= last;
}
res
}
pub struct Combinations<M: BaseModInt>
where
M::T: AsIndex,
{
fact: Vec<M>,
inv_fact: Vec<M>,
}
impl<M: BaseModInt + AsIndex> Combinations<M>
where
M::T: AsIndex,
{
pub fn new(len: usize) -> Self {
Self {
fact: factorials(len),
inv_fact: inverse_factorials(len),
}
}
pub fn c(&self, n: usize, k: usize) -> M {
if n < k {
M::zero()
} else {
self.fact[n] * self.inv_fact[k] * self.inv_fact[n - k]
}
}
pub fn comb_with_rep(&self, n: usize, k: usize) -> M {
self.c(n + k - 1, k)
}
pub fn c_inv(&self, n: usize, k: usize) -> M {
self.inv_fact[n] * self.fact[k] * self.fact[n - k]
}
pub fn fact(&self, n: usize) -> M {
self.fact[n]
}
pub fn inv_fact(&self, n: usize) -> M {
self.inv_fact[n]
}
}
pub fn combinations<M: BaseModInt + AsIndex>(n: usize, mut k: usize) -> M {
if k > n {
return M::zero();
}
if k > n - k {
k = n - k;
}
let mut res = M::one();
for i in n - k + 1..=n {
res *= M::from_index(i);
}
res /= factorial(k);
res
}
}
pub mod num_traits {
pub mod algebra {
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Div;
use std::ops::DivAssign;
use std::ops::Mul;
use std::ops::MulAssign;
use std::ops::Neg;
use std::ops::Rem;
use std::ops::RemAssign;
use std::ops::Sub;
use std::ops::SubAssign;
pub trait Zero {
fn zero() -> Self;
}
pub trait One {
fn one() -> Self;
}
pub trait AdditionMonoid: Add<Output = Self> + AddAssign + Zero + Eq + Sized {}
impl<T: Add<Output = Self> + AddAssign + Zero + Eq> AdditionMonoid for T {}
pub trait AdditionMonoidWithSub: AdditionMonoid + Sub<Output = Self> + SubAssign {}
impl<T: AdditionMonoid + Sub<Output = Self> + SubAssign> AdditionMonoidWithSub for T {}
pub trait AdditionGroup: AdditionMonoidWithSub + Neg<Output = Self> {}
impl<T: AdditionMonoidWithSub + Neg<Output = Self>> AdditionGroup for T {}
pub trait MultiplicationMonoid: Mul<Output = Self> + MulAssign + One + Eq + Sized {}
impl<T: Mul<Output = Self> + MulAssign + One + Eq> MultiplicationMonoid for T {}
pub trait IntegerMultiplicationMonoid:
MultiplicationMonoid + Div<Output = Self> + Rem<Output = Self> + DivAssign + RemAssign
{
}
impl<T: MultiplicationMonoid + Div<Output = Self> + Rem<Output = Self> + DivAssign + RemAssign>
IntegerMultiplicationMonoid for T
{
}
pub trait MultiplicationGroup:
MultiplicationMonoid + Div<Output = Self> + DivAssign + Invertible<Output = Self>
{
}
impl<T: MultiplicationMonoid + Div<Output = Self> + DivAssign + Invertible<Output = Self>>
MultiplicationGroup for T
{
}
pub trait SemiRing: AdditionMonoid + MultiplicationMonoid {}
impl<T: AdditionMonoid + MultiplicationMonoid> SemiRing for T {}
pub trait SemiRingWithSub: AdditionMonoidWithSub + SemiRing {}
impl<T: AdditionMonoidWithSub + SemiRing> SemiRingWithSub for T {}
pub trait Ring: SemiRing + AdditionGroup {}
impl<T: SemiRing + AdditionGroup> Ring for T {}
pub trait IntegerSemiRing: SemiRing + IntegerMultiplicationMonoid {}
impl<T: SemiRing + IntegerMultiplicationMonoid> IntegerSemiRing for T {}
pub trait IntegerSemiRingWithSub: SemiRingWithSub + IntegerSemiRing {}
impl<T: SemiRingWithSub + IntegerSemiRing> IntegerSemiRingWithSub for T {}
pub trait IntegerRing: IntegerSemiRing + Ring {}
impl<T: IntegerSemiRing + Ring> IntegerRing for T {}
pub trait Field: Ring + MultiplicationGroup {}
impl<T: Ring + MultiplicationGroup> Field for T {}
macro_rules! zero_one_integer_impl {
($($t: ident)+) => {$(
impl Zero for $t {
fn zero() -> Self {
0
}
}
impl One for $t {
fn one() -> Self {
1
}
}
)+};
}
zero_one_integer_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod as_index {
pub trait AsIndex {
fn from_index(idx: usize) -> Self;
fn to_index(self) -> usize;
}
macro_rules! from_index_impl {
($($t: ident)+) => {$(
impl AsIndex for $t {
fn from_index(idx: usize) -> Self {
idx as $t
}
fn to_index(self) -> usize {
self as usize
}
}
)+};
}
from_index_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod invertible {
pub trait Invertible {
type Output;
fn inv(&self) -> Option<Self::Output>;
}
}
pub mod wideable {
use std::convert::From;
pub trait Wideable: Sized {
type W: From<Self>;
fn downcast(w: Self::W) -> Self;
}
macro_rules! wideable_impl {
($($t: ident $w: ident),+) => {$(
impl Wideable for $t {
type W = $w;
fn downcast(w: Self::W) -> Self {
w as $t
}
}
)+};
}
wideable_impl!(i64 i128, i32 i64, i16 i32, i8 i16, u64 u128, u32 u64, u16 u32, u8 u16);
}
}
pub mod num_utils {
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoid;
use crate::algo_lib::numbers::num_traits::algebra::IntegerRing;
use crate::algo_lib::numbers::num_traits::algebra::MultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
pub fn factorials<T: MultiplicationMonoid + Copy + AsIndex>(len: usize) -> Vec<T> {
let mut res = Vec::new();
if len > 0 {
res.push(T::one());
}
while res.len() < len {
res.push((*res.last().unwrap()) * T::from_index(res.len()));
}
res
}
pub fn powers<T: MultiplicationMonoid + Copy>(base: T, len: usize) -> Vec<T> {
let mut res = Vec::new();
if len > 0 {
res.push(T::one());
}
while res.len() < len {
res.push((*res.last().unwrap()) * base);
}
res
}
pub struct Powers<T: MultiplicationMonoid + Copy> {
small: Vec<T>,
big: Vec<T>,
}
impl<T: MultiplicationMonoid + Copy> Powers<T> {
pub fn new(base: T, len: usize) -> Self {
let small = powers(base, len);
let big = powers(small[len - 1] * base, len);
Self { small, big }
}
pub fn power(&self, exp: usize) -> T {
debug_assert!(exp < self.small.len() * self.small.len());
self.big[exp / self.small.len()] * self.small[exp % self.small.len()]
}
}
pub fn factorial<T: MultiplicationMonoid + AsIndex>(n: usize) -> T {
let mut res = T::one();
for i in 1..=n {
res *= T::from_index(i);
}
res
}
pub trait PartialSums<T> {
fn partial_sums(&self) -> Vec<T>;
}
impl<T: AdditionMonoid + Copy> PartialSums<T> for [T] {
fn partial_sums(&self) -> Vec<T> {
let mut res = Vec::with_capacity(self.len() + 1);
res.push(T::zero());
for i in self.iter() {
res.push(*res.last().unwrap() + *i);
}
res
}
}
pub trait UpperDiv {
fn upper_div(self, other: Self) -> Self;
}
impl<T: IntegerRing + Copy> UpperDiv for T {
fn upper_div(self, other: Self) -> Self {
(self + other - Self::one()) / other
}
}
}
pub mod number_ext {
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRing;
use crate::algo_lib::numbers::num_traits::algebra::MultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use std::ops::Mul;
pub trait Power {
#[must_use]
fn power<T: IntegerSemiRing + Copy>(&self, exp: T) -> Self;
}
impl<S: MultiplicationMonoid + Copy> Power for S {
fn power<T: IntegerSemiRing + Copy>(&self, exp: T) -> Self {
if exp == T::zero() {
S::one()
} else {
let mut res = self.power(exp / (T::one() + T::one()));
res *= res;
if exp % (T::one() + T::one()) == T::one() {
res *= *self;
}
res
}
}
}
pub trait NumDigs {
fn num_digs(&self) -> usize;
}
impl<S: IntegerSemiRing + AsIndex + Copy> NumDigs for S {
fn num_digs(&self) -> usize {
let mut copy = *self;
let ten = S::from_index(10);
let mut res = 0;
while copy != S::zero() {
copy /= ten;
res += 1;
}
res
}
}
pub trait Square {
fn square(self) -> Self;
}
impl<T: Mul<Output = T> + Copy> Square for T {
fn square(self) -> Self {
self * self
}
}
}
}
}
fn main() {
let mut sin = std::io::stdin();
let input = algo_lib::io::input::Input::new(&mut sin);
let mut stdout = std::io::stdout();
let output = algo_lib::io::output::Output::new(&mut stdout);
solution::run(input, output);
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 370ms
memory: 502028kb
input:
4 3 2 1 1 20 23 8000 8000
output:
374341634 1 111675632 994279778
result:
ok 4 tokens
Test #2:
score: 0
Accepted
time: 383ms
memory: 502164kb
input:
5 60 26 33 95 18 89 82 12 77 36
output:
945602338 254913692 403396795 820508695 360125985
result:
ok 5 tokens
Test #3:
score: 0
Accepted
time: 372ms
memory: 502136kb
input:
5 23 13 95 8 73 19 72 74 23 51
output:
788774542 935467825 483603650 274447212 738760583
result:
ok 5 tokens
Test #4:
score: 0
Accepted
time: 380ms
memory: 502164kb
input:
5 7 79 47 12 64 29 23 59 88 21
output:
238359778 424364643 993714623 760177301 865871793
result:
ok 5 tokens
Test #5:
score: 0
Accepted
time: 368ms
memory: 502108kb
input:
5 39 47 22 33 2 58 43 45 32 67
output:
68068469 21035974 735626561 965644028 137192045
result:
ok 5 tokens
Test #6:
score: 0
Accepted
time: 375ms
memory: 502224kb
input:
5 57 73 20 64 18 72 56 64 9 58
output:
218207240 814770590 121270366 636721674 420274847
result:
ok 5 tokens
Test #7:
score: 0
Accepted
time: 376ms
memory: 502116kb
input:
5 100 100 100 99 99 100 98 99 99 97
output:
585389012 131732771 619127511 549657738 490584077
result:
ok 5 tokens
Test #8:
score: 0
Accepted
time: 375ms
memory: 502464kb
input:
1922 4663 5021 7459 306 3249 6943 4902 4260 6118 5364 4997 7021 6772 3346 3916 7327 7156 4792 1228 5381 3240 7026 131 5713 1120 5334 2186 610 7638 2846 891 6274 5363 426 1335 7417 2127 396 323 7781 5435 1922 4989 5238 2886 3788 5413 1384 7624 4245 7191 6758 7755 5835 7660 1787 1043 7586 803 7889 79 ...
output:
672342508 406758717 456109836 583347519 254351863 547587964 177045319 935533988 555369350 136991350 790497273 429246740 670208582 782070778 169184793 771435402 251034885 528072506 303570823 257245963 629853925 267752975 350150586 786769060 44222606 607226242 320315817 861879910 752261031 341472947 2...
result:
ok 1922 tokens
Test #9:
score: 0
Accepted
time: 379ms
memory: 502504kb
input:
1569 1690 3118 4489 1453 6866 3161 6664 1290 2600 7962 6689 4642 522 772 2162 4794 3190 5987 3327 4938 6130 3823 6941 5425 3091 6213 3025 388 5330 3690 3161 6492 1740 5873 5530 1458 2496 6781 6287 5635 662 3877 3505 5138 2511 2028 3500 859 7572 813 2520 3943 7377 4768 6158 1882 7427 1702 4296 5159 5...
output:
786392950 680031668 677629004 801851613 786349751 79816839 959519914 318092993 339917671 724667845 890615671 100962701 589915015 941504560 820459949 486565344 823734064 220460851 576680186 554430485 361102164 218914963 840663949 777667686 736007308 919520675 863371619 66677855 637862969 67422276 384...
result:
ok 1569 tokens
Test #10:
score: 0
Accepted
time: 381ms
memory: 502376kb
input:
1181 4017 5052 5241 7494 7719 3875 7903 143 7280 2239 6098 2785 4900 5047 3542 4892 3011 430 4358 3184 1473 1501 2732 5656 6806 7106 6079 4418 4893 233 1746 3558 3801 650 4506 970 7836 5225 1970 1822 3342 7672 3519 1017 6258 3172 6871 3994 4143 3721 1752 2936 5806 2553 1727 3701 6464 2302 2048 3091 ...
output:
648881231 526073149 469264135 392921762 374237236 765018788 699026377 457948355 693169225 754094043 700515631 122741833 428610910 661965148 268857241 313001621 686530925 177273994 339148514 571456944 973936686 176745436 23414882 360870357 623038194 895354617 386646311 288047747 236022755 955017813 1...
result:
ok 1181 tokens
Test #11:
score: 0
Accepted
time: 374ms
memory: 502372kb
input:
1080 7499 4465 5556 2341 808 1986 3404 6901 4609 4168 235 5744 5131 7261 6616 1993 4624 3943 5843 6392 4889 2743 386 6670 1188 23 4216 4225 1193 1295 6097 4160 710 2728 7146 4193 5425 4148 6206 7462 7147 1808 2381 1254 4193 1297 1359 233 991 6979 5009 6963 1824 2135 1078 6208 2893 5858 320 4173 4937...
output:
584491148 616649457 512306930 528213999 550156793 344729669 779502829 828764040 365090398 371482124 273983459 617971432 137019685 400487464 761520033 143391408 908639433 294086517 926654429 723576006 993426946 572674399 178336952 402120004 148856064 897242602 390050708 850225145 605879501 962941650 ...
result:
ok 1080 tokens
Test #12:
score: 0
Accepted
time: 377ms
memory: 502316kb
input:
1534 2137 7885 2676 2513 53 3021 1623 5195 660 4999 2881 7697 6034 6429 4724 4014 5986 266 7826 726 4086 6628 7498 6114 4801 4415 5037 4206 700 6054 3497 476 1715 5892 6009 6340 1251 2345 2819 4107 7544 864 3138 4179 3909 912 180 4496 4727 2930 1057 7077 4123 2560 4963 4100 7118 463 2945 935 6573 41...
output:
676937061 816416208 899106800 778722088 621854770 637694747 789726622 647248717 143759992 290955099 204045987 17260543 508242895 836696138 605720517 462338702 426815143 443255417 341689094 660082176 461660684 531200268 467927798 816405934 307396775 786033585 765478425 774747686 67909522 155061063 47...
result:
ok 1534 tokens
Test #13:
score: 0
Accepted
time: 1057ms
memory: 525996kb
input:
300000 1983 855 7767 4477 6925 7526 7306 5358 3987 46 5716 3789 4487 4391 4358 7525 933 1015 953 546 5716 5487 968 6561 2932 6558 6796 1429 4864 4211 5955 4414 6657 5171 2784 3725 1139 7304 553 3163 7248 6772 1977 6216 4701 7267 6130 4055 5688 1364 1335 4326 2633 3945 7851 5521 6474 2532 6869 5201 2...
output:
917986185 514093688 240004856 10138263 106086887 486293160 462563200 380236329 178495199 768072852 293049871 679765965 19413063 914310451 303877752 97576016 551398628 294935753 497649688 625770227 916721949 945723005 793837895 598750153 811171822 281042931 224310375 229099648 232754408 173968951 334...
result:
ok 300000 tokens
Test #14:
score: 0
Accepted
time: 1079ms
memory: 526396kb
input:
300000 6276 3969 1337 287 69 4971 4553 4420 4304 107 836 5154 7039 7495 4074 5597 3321 6214 5997 5958 1357 67 5347 5263 5228 5204 6067 7567 3498 226 1830 3989 7897 3908 4547 714 1973 4138 3392 2046 6781 2623 7423 7027 3219 1631 688 6768 1270 5667 1911 1106 4914 755 4060 6194 5588 6416 5379 3593 4950...
output:
785609765 389521714 617648697 133397962 663080285 932116327 864145458 250419436 926868327 231968290 706343931 34357834 259117474 30429506 802394434 962282557 421143424 325071266 930611818 413209658 588520237 879895836 293550595 779472804 703506662 997419552 167326709 571013401 948481475 873418350 52...
result:
ok 300000 tokens
Test #15:
score: 0
Accepted
time: 1070ms
memory: 526172kb
input:
300000 172 7671 2377 1841 772 2572 897 2774 7862 7766 563 7835 50 5627 3975 332 3125 4092 6642 7913 377 4237 5378 2346 7235 484 7254 4026 5032 189 698 3244 5656 1277 42 5418 294 7339 6054 5619 5273 6487 3381 4739 1652 5241 5455 6606 5194 1556 2248 5307 6266 94 6669 4982 4033 4379 6666 4863 7785 583 ...
output:
690315780 651031191 910258157 142140073 777756320 339555304 856925271 481764268 804784924 892959827 162363106 880216583 28750709 919204633 590976688 235862971 115143352 552437269 440186544 342438715 203287097 208201535 473851494 630433067 795957931 121121486 655185544 120192487 18559533 512410924 14...
result:
ok 300000 tokens
Test #16:
score: 0
Accepted
time: 1059ms
memory: 526108kb
input:
300000 7687 5348 7170 7128 1126 3094 1811 2132 4535 2558 6168 62 1913 315 454 6832 2620 979 6268 2470 7745 4962 5836 455 2548 2645 1190 4820 1664 7069 1853 3559 1684 324 2964 2375 6535 2140 5793 6520 2089 2949 6810 6376 3938 1105 3321 2276 1764 7871 7238 4463 6621 6709 4794 1247 1193 3711 7945 25 75...
output:
467980791 680962696 898655348 87851601 574364215 617075952 975724718 232344677 97747094 798035755 544312119 750213987 398352588 468271115 911224185 789740750 889993565 757589351 219602000 508186836 143616463 496959998 957512294 48894767 747840016 237688107 834496842 452902067 436640761 68924558 4766...
result:
ok 300000 tokens
Test #17:
score: 0
Accepted
time: 1063ms
memory: 526288kb
input:
300000 3651 4395 598 2124 7806 1885 6102 3232 1632 4425 2814 2949 2885 4010 719 5821 945 382 3259 3899 1193 2658 3681 176 6978 3339 5065 458 7910 7330 7480 2560 1144 4193 3047 5955 690 5384 6928 5609 238 904 6819 6617 2297 2464 1956 4427 3070 7665 57 5624 1382 7277 1510 931 5413 6319 4135 5153 1245 ...
output:
185080421 622515437 953285449 259657392 382766568 389748070 912098350 791812015 122470478 542646121 189378193 481103802 38378800 282397881 456885301 463133196 542482622 956189657 306447176 892824103 231973605 607936904 612962412 787715604 946988413 397452805 443819486 441909715 443478773 675662739 2...
result:
ok 300000 tokens
Test #18:
score: 0
Accepted
time: 932ms
memory: 526124kb
input:
300000 5511 1592 3091 222 3042 2846 4996 1848 2759 719 339 41 7833 6657 6578 4870 5836 3918 3287 2592 6888 254 323 257 3894 762 2781 147 6338 4197 2401 5526 309 111 499 475 68 1 1791 1498 1139 172 7367 5346 1326 1086 6056 3244 1539 870 2161 577 6899 4934 3222 2409 5094 4945 1252 389 7532 3877 4849 2...
output:
308162096 926831023 97466439 381502673 879141892 288558285 376988538 114780505 967786299 109837829 456357766 152648543 358087181 727740397 203822224 512742419 592251017 205442121 1 187347956 440265112 31975034 944117166 277099223 807372439 313788153 396485979 416038692 118014328 380422322 384451082 ...
result:
ok 300000 tokens
Test #19:
score: 0
Accepted
time: 931ms
memory: 526072kb
input:
300000 5511 2811 3091 225 3042 1281 4996 821 2759 267 339 292 7833 515 6578 5344 5836 1128 3287 398 6888 5910 323 266 3894 3721 2781 2271 6338 5322 6838 6497 309 243 499 486 68 11 1791 100 1139 514 7367 5113 1326 747 6056 1604 1539 782 2161 762 6899 4749 3222 2011 5094 3978 1252 623 7532 5477 4849 4...
output:
665054891 300867667 348283279 466053547 45744379 708735980 593404766 831832507 489279444 573407999 597639718 5766230 375599902 486548670 501927978 980593373 969955705 448325802 388400601 262385137 375376816 110122988 737706874 150359153 575621812 804184716 68665586 818047613 692689346 78602127 45512...
result:
ok 300000 tokens
Test #20:
score: 0
Accepted
time: 922ms
memory: 526376kb
input:
300000 5511 413 3091 2856 3042 1024 4996 3213 2759 105 339 327 7833 5988 6578 1636 5836 315 3287 1972 6888 1326 323 60 3894 816 2781 1712 6338 4382 2852 7641 309 57 499 167 68 23 1791 1375 1139 348 7367 6505 1326 435 6056 4617 1539 1133 2161 910 6899 1763 3222 1481 5094 2477 1252 1156 7532 6557 4849...
output:
485659367 677896371 51153808 69443182 412971885 818481416 849977792 331829138 55724792 462907888 637926 406804012 381350405 51624478 359208029 272155650 163436382 342656855 200714626 498916202 182274510 677459983 991151110 396383019 392439555 63570810 520284517 966012692 88444228 86200285 555967449 ...
result:
ok 300000 tokens
Test #21:
score: 0
Accepted
time: 925ms
memory: 526416kb
input:
300000 5511 2520 3091 2007 3042 2527 4996 267 2759 1311 339 7 7833 5969 6578 5180 5836 4504 3287 824 6888 1800 323 188 3894 2703 2781 113 6338 5373 210 667 309 5 499 463 68 45 1791 1776 1139 217 7367 6534 1326 193 6056 4824 1539 64 2161 626 6899 2131 3222 2304 5094 908 1252 622 7532 571 4849 1266 15...
output:
476330360 341129155 87686760 780287663 27737410 601067754 621911465 112461167 976022023 494331271 75971592 561865913 585445560 580978232 272409206 301199669 509769247 189882720 370830663 729977839 290413155 663712832 115843838 947770059 572260971 688396109 806982866 335384041 666428123 733355123 403...
result:
ok 300000 tokens
Test #22:
score: 0
Accepted
time: 926ms
memory: 526276kb
input:
300000 5511 2723 3091 2210 3042 1678 4996 3350 2759 1717 339 59 7833 6785 6578 1468 5836 5509 3287 2451 6888 4895 323 38 3894 2668 2781 2757 6338 5735 139 3773 309 296 499 359 68 51 1791 681 1139 990 7367 745 1326 327 6056 4864 1539 1125 2161 808 6899 890 3222 1023 5094 818 1252 185 7532 1083 4849 1...
output:
122256708 329468041 972582618 696900189 185355879 798415905 911105222 943525716 635145786 793642508 954014637 300072137 198622306 632297009 788106407 790602929 474908621 312319885 494386936 195749245 997359493 881353961 668060322 157183412 32778140 733123188 104542588 116382314 860154073 47295 78564...
result:
ok 300000 tokens
Test #23:
score: 0
Accepted
time: 1675ms
memory: 526096kb
input:
300000 7522 7956 7746 7848 7995 7694 7479 7992 7878 7976 7532 7658 7679 7755 7462 7709 7610 7495 7877 7995 7915 7608 7883 7677 7467 7658 7615 7815 7521 7676 7455 7891 7868 7896 7634 7704 7869 7590 7471 7573 7472 7678 7885 7539 7983 7974 7478 7479 7705 7827 7675 7615 7915 7597 7644 7511 7903 7966 750...
output:
350858640 985201186 270505812 117456150 344107653 461416294 951152728 812878714 422195931 502806704 124570242 713987345 272798186 110562310 722669359 200627964 808703774 749707180 560860878 63011161 961348423 407734207 629246603 741475119 234863886 992855605 920110738 57955523 124147954 685852042 92...
result:
ok 300000 tokens
Extra Test:
score: 0
Extra Test Passed