// https://judge.eluminatis-of-lu.com/contest/676ffd92569fb90008aac7da/1151
use crate::algo_lib::collections::iter_ext::iter_copied::ItersCopied;
use crate::algo_lib::collections::min_max::MinimMaxim;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
use crate::algo_lib::numbers::primes::factorize::all_divisors;
type PreCalc = ();
fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
let n = input.read_size();
let a = input.read_size_vec(n);
let max = a.copy_max();
let ad: Vec<Vec<usize>> = all_divisors(max + 1, false);
let mut cnt = vec![0; max + 1];
for i in a {
for j in ad[i].copy_iter() {
cnt[j] += 1;
}
}
let mut ans = vec![0; n];
for i in 1..=max {
if cnt[i] > 0 {
ans[cnt[i] - 1] = i;
}
}
for i in (1..n).rev() {
let cand = ans[i];
ans[i - 1].maxim(cand);
}
out.print_line(ans);
}
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,
}
}
fn main() {
let mut sin = std::io::stdin();
let input = crate::algo_lib::io::input::Input::new(&mut sin);
let mut stdout = std::io::stdout();
let output = crate::algo_lib::io::output::Output::new(&mut stdout);
run(input, output);
}
pub mod algo_lib {
pub mod collections {
pub mod bit_set {
use crate::algo_lib::collections::iter_ext::iter_copied::ItersCopied;
use crate::algo_lib::numbers::num_traits::bit_ops::BitOps;
use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, Index, ShlAssign, ShrAssign};
const TRUE: bool = true;
const FALSE: bool = false;
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct BitSet {
data: Vec<u64>,
len: usize,
}
impl BitSet {
pub fn new(len: usize) -> Self {
let data_len = if len == 0 { 0 } else { Self::index(len - 1) + 1 };
Self {
data: vec![0; data_len],
len,
}
}
pub fn from_slice(len: usize, set: &[usize]) -> Self {
let mut res = Self::new(len);
for &i in set {
res.set(i);
}
res
}
pub fn set(&mut self, at: usize) {
assert!(at < self.len);
self.data[Self::index(at)].set_bit(at & 63);
}
pub fn unset(&mut self, at: usize) {
assert!(at < self.len);
self.data[Self::index(at)].unset_bit(at & 63);
}
pub fn change(&mut self, at: usize, value: bool) {
if value {
self.set(at);
} else {
self.unset(at);
}
}
pub fn flip(&mut self, at: usize) {
self.change(at, !self[at]);
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.len
}
pub fn fill(&mut self, value: bool) {
self.data.fill(if value { std::u64::MAX } else { 0 });
if value {
self.fix_last();
}
}
pub fn is_superset(&self, other: &Self) -> bool {
assert_eq!(self.len, other.len);
for (we, them) in self.data.copy_zip(&other.data) {
if (we & them) != them {
return false;
}
}
true
}
pub fn is_subset(&self, other: &Self) -> bool {
other.is_superset(self)
}
pub fn iter(&self) -> BitSetIter<'_> {
self.into_iter()
}
fn index(at: usize) -> usize {
at >> 6
}
pub fn count_ones(&self) -> usize {
self.data.iter().map(|x| x.count_ones() as usize).sum()
}
fn fix_last(&mut self) {
if self.len & 63 != 0 {
let mask = (1 << (self.len & 63)) - 1;
*self.data.last_mut().unwrap() &= mask;
}
}
}
pub struct BitSetIter<'s> {
at: usize,
inside: usize,
set: &'s BitSet,
}
impl<'s> Iterator for BitSetIter<'s> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while self.at < self.set.data.len()
&& (self.inside == 64 || (self.set.data[self.at] >> self.inside) == 0)
{
self.at += 1;
self.inside = 0;
}
if self.at == self.set.data.len() {
None
} else {
self.inside
+= (self.set.data[self.at] >> self.inside).trailing_zeros() as usize;
let res = self.at * 64 + self.inside;
self.inside += 1;
Some(res)
}
}
}
impl<'a> IntoIterator for &'a BitSet {
type Item = usize;
type IntoIter = BitSetIter<'a>;
fn into_iter(self) -> Self::IntoIter {
BitSetIter {
at: 0,
inside: 0,
set: self,
}
}
}
impl BitOrAssign<&BitSet> for BitSet {
fn bitor_assign(&mut self, rhs: &BitSet) {
assert_eq!(self.len, rhs.len);
for (i, &j) in self.data.iter_mut().zip(rhs.data.iter()) {
*i |= j;
}
}
}
impl BitAndAssign<&BitSet> for BitSet {
fn bitand_assign(&mut self, rhs: &BitSet) {
assert_eq!(self.len, rhs.len);
for (i, &j) in self.data.iter_mut().zip(rhs.data.iter()) {
*i &= j;
}
}
}
impl BitXorAssign<&BitSet> for BitSet {
fn bitxor_assign(&mut self, rhs: &BitSet) {
assert_eq!(self.len, rhs.len);
for (i, &j) in self.data.iter_mut().zip(rhs.data.iter()) {
*i ^= j;
}
}
}
impl ShlAssign<usize> for BitSet {
fn shl_assign(&mut self, rhs: usize) {
if rhs == 0 {
return;
}
if rhs >= self.len {
self.fill(false);
return;
}
let small_shift = rhs & 63;
if small_shift != 0 {
let mut carry = 0;
for data in self.data.iter_mut() {
let new_carry = (*data) >> (64 - small_shift);
*data <<= small_shift;
*data |= carry;
carry = new_carry;
}
}
let big_shift = rhs >> 6;
if big_shift != 0 {
self.data.rotate_right(big_shift);
self.data[..big_shift].fill(0);
}
self.fix_last();
}
}
impl ShrAssign<usize> for BitSet {
fn shr_assign(&mut self, rhs: usize) {
if rhs == 0 {
return;
}
if rhs >= self.len {
self.fill(false);
return;
}
let small_shift = rhs & 63;
if small_shift != 0 {
let mut carry = 0;
for data in self.data.iter_mut().rev() {
let new_carry = (*data) << (64 - small_shift);
*data >>= small_shift;
*data |= carry;
carry = new_carry;
}
}
let big_shift = rhs >> 6;
if big_shift != 0 {
self.data.rotate_left(big_shift);
let from = self.data.len() - big_shift;
self.data[from..].fill(0);
}
}
}
impl Index<usize> for BitSet {
type Output = bool;
fn index(&self, at: usize) -> &Self::Output {
assert!(at < self.len);
if self.data[Self::index(at)].is_set(at & 63) { &TRUE } else { &FALSE }
}
}
impl From<Vec<bool>> for BitSet {
fn from(data: Vec<bool>) -> Self {
let mut res = Self::new(data.len());
for (i, &value) in data.iter().enumerate() {
res.change(i, value);
}
res
}
}
}
pub mod fx_hash_map {
use std::cell::Cell;
use std::convert::TryInto;
use std::time::SystemTime;
use std::{
collections::{HashMap, HashSet},
hash::{BuildHasherDefault, Hasher},
ops::BitXor,
};
pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>;
#[derive(Default)]
pub struct FxHasher {
hash: usize,
}
thread_local! {
static K : Cell < usize > = Cell::new(((SystemTime::UNIX_EPOCH.elapsed().unwrap()
.as_nanos().wrapping_mul(2) + 1) & 0xFFFFFFFFFFFFFFFF) as usize)
}
impl FxHasher {
#[inline]
fn add_to_hash(&mut self, i: usize) {
self.hash = self.hash.rotate_left(5).bitxor(i).wrapping_mul(K.get());
}
}
impl Hasher for FxHasher {
#[inline]
fn write(&mut self, mut bytes: &[u8]) {
let read_usize = |bytes: &[u8]| u64::from_ne_bytes(
bytes[..8].try_into().unwrap(),
);
let mut hash = FxHasher { hash: self.hash };
while bytes.len() >= 8 {
hash.add_to_hash(read_usize(bytes) as usize);
bytes = &bytes[8..];
}
if bytes.len() >= 4 {
hash.add_to_hash(
u32::from_ne_bytes(bytes[..4].try_into().unwrap()) as usize,
);
bytes = &bytes[4..];
}
if bytes.len() >= 2 {
hash.add_to_hash(
u16::from_ne_bytes(bytes[..2].try_into().unwrap()) as usize,
);
bytes = &bytes[2..];
}
if !bytes.is_empty() {
hash.add_to_hash(bytes[0] as usize);
}
self.hash = hash.hash;
}
#[inline]
fn write_u8(&mut self, i: u8) {
self.add_to_hash(i as usize);
}
#[inline]
fn write_u16(&mut self, i: u16) {
self.add_to_hash(i as usize);
}
#[inline]
fn write_u32(&mut self, i: u32) {
self.add_to_hash(i as usize);
}
#[inline]
fn write_u64(&mut self, i: u64) {
self.add_to_hash(i as usize);
}
#[inline]
fn write_usize(&mut self, i: usize) {
self.add_to_hash(i);
}
#[inline]
fn finish(&self) -> u64 {
self.hash as u64
}
}
}
pub mod iter_ext {
pub mod iter_copied {
use std::iter::{
Chain, Copied, Enumerate, Filter, Map, Rev, Skip, StepBy, Sum, Take, Zip,
};
pub trait ItersCopied<'a, T: 'a + Copy>: Sized + 'a
where
&'a Self: IntoIterator<Item = &'a T>,
{
fn copy_iter(&'a self) -> Copied<<&'a Self as IntoIterator>::IntoIter> {
self.into_iter().copied()
}
fn copy_enumerate(
&'a self,
) -> Enumerate<Copied<<&'a Self as IntoIterator>::IntoIter>> {
self.copy_iter().enumerate()
}
fn copy_rev(&'a self) -> Rev<Copied<<&'a Self as IntoIterator>::IntoIter>>
where
Copied<<&'a Self as IntoIterator>::IntoIter>: DoubleEndedIterator,
{
self.copy_iter().rev()
}
fn copy_skip(
&'a self,
n: usize,
) -> Skip<Copied<<&'a Self as IntoIterator>::IntoIter>> {
self.copy_iter().skip(n)
}
fn copy_take(
&'a self,
n: usize,
) -> Take<Copied<<&'a Self as IntoIterator>::IntoIter>> {
self.copy_iter().take(n)
}
fn copy_chain<V>(
&'a self,
chained: &'a V,
) -> Chain<
Copied<<&'a Self as IntoIterator>::IntoIter>,
Copied<<&'a V as IntoIterator>::IntoIter>,
>
where
&'a V: IntoIterator<Item = &'a T>,
{
self.copy_iter().chain(chained.into_iter().copied())
}
fn copy_zip<V>(
&'a self,
other: &'a V,
) -> Zip<
Copied<<&'a Self as IntoIterator>::IntoIter>,
Copied<<&'a V as IntoIterator>::IntoIter>,
>
where
&'a V: IntoIterator<Item = &'a T>,
{
self.copy_iter().zip(other.into_iter().copied())
}
fn copy_max(&'a self) -> T
where
T: Ord,
{
self.copy_iter().max().unwrap()
}
fn copy_max_by_key<B, F>(&'a self, f: F) -> T
where
F: FnMut(&T) -> B,
B: Ord,
{
self.copy_iter().max_by_key(f).unwrap()
}
fn copy_min(&'a self) -> T
where
T: Ord,
{
self.copy_iter().min().unwrap()
}
fn copy_min_by_key<B, F>(&'a self, f: F) -> T
where
F: FnMut(&T) -> B,
B: Ord,
{
self.copy_iter().min_by_key(f).unwrap()
}
fn copy_sum(&'a self) -> T
where
T: Sum<T>,
{
self.copy_iter().sum()
}
fn copy_map<F, U>(
&'a self,
f: F,
) -> Map<Copied<<&'a Self as IntoIterator>::IntoIter>, F>
where
F: FnMut(T) -> U,
{
self.copy_iter().map(f)
}
fn copy_all(&'a self, f: impl FnMut(T) -> bool) -> bool {
self.copy_iter().all(f)
}
fn copy_any(&'a self, f: impl FnMut(T) -> bool) -> bool {
self.copy_iter().any(f)
}
fn copy_step_by(
&'a self,
step: usize,
) -> StepBy<Copied<<&'a Self as IntoIterator>::IntoIter>> {
self.copy_iter().step_by(step)
}
fn copy_filter<F: FnMut(&T) -> bool>(
&'a self,
f: F,
) -> Filter<Copied<<&'a Self as IntoIterator>::IntoIter>, F> {
self.copy_iter().filter(f)
}
fn copy_fold<Acc, F>(&'a self, init: Acc, f: F) -> Acc
where
F: FnMut(Acc, T) -> Acc,
{
self.copy_iter().fold(init, f)
}
fn copy_reduce<F>(&'a self, f: F) -> Option<T>
where
F: FnMut(T, T) -> T,
{
self.copy_iter().reduce(f)
}
fn copy_position<P>(&'a self, predicate: P) -> Option<usize>
where
P: FnMut(T) -> bool,
{
self.copy_iter().position(predicate)
}
fn copy_find(&'a self, val: T) -> Option<usize>
where
T: PartialEq,
{
self.copy_iter().position(|x| x == val)
}
fn copy_count(&'a self, val: T) -> usize
where
T: PartialEq,
{
self.copy_iter().filter(|&x| x == val).count()
}
}
impl<'a, U: 'a, T: 'a + Copy> ItersCopied<'a, T> for U
where
&'a U: IntoIterator<Item = &'a T>,
{}
}
}
pub mod min_max {
pub trait MinimMaxim<Rhs = Self>: PartialOrd + Sized {
fn minim(&mut self, other: Rhs) -> bool;
fn maxim(&mut self, other: Rhs) -> bool;
}
impl<T: PartialOrd> MinimMaxim for T {
fn minim(&mut self, other: Self) -> bool {
if other < *self {
*self = other;
true
} else {
false
}
}
fn maxim(&mut self, other: Self) -> bool {
if other > *self {
*self = other;
true
} else {
false
}
}
}
impl<T: PartialOrd> MinimMaxim<T> for Option<T> {
fn minim(&mut self, other: T) -> bool {
match self {
None => {
*self = Some(other);
true
}
Some(v) => v.minim(other),
}
}
fn maxim(&mut self, other: T) -> bool {
match self {
None => {
*self = Some(other);
true
}
Some(v) => v.maxim(other),
}
}
}
}
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 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 sorted {
pub trait Sorted {
fn sorted(self) -> Self;
}
impl<T: Ord> Sorted for Vec<T> {
fn sorted(mut self) -> Self {
self.sort();
self
}
}
}
}
}
pub mod io {
pub mod input {
use crate::algo_lib::collections::vec_ext::default::default_vec;
use std::io::Read;
use std::mem::MaybeUninit;
pub struct Input<'s> {
input: &'s mut (dyn Read + Send),
buf: Vec<u8>,
at: usize,
buf_read: usize,
eol: bool,
}
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,
eol: true,
}
}
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,
eol: true,
}
}
pub fn get(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
self.at += 1;
if res == b'\r' {
self.eol = true;
if self.refill_buffer() && self.buf[self.at] == b'\n' {
self.at += 1;
}
return Some(b'\n');
}
self.eol = res == 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) }
}
pub fn is_exhausted(&mut self) -> bool {
self.peek().is_none()
}
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 fn is_eol(&self) -> bool {
self.eol
}
}
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)
}
}
impl<T: Readable, const SIZE: usize> Readable for [T; SIZE] {
fn read(input: &mut Input) -> Self {
unsafe {
let mut res = MaybeUninit::<[T; SIZE]>::uninit();
for i in 0..SIZE {
let ptr: *mut T = (*res.as_mut_ptr()).as_mut_ptr();
ptr.add(i).write(input.read::<T>());
}
res.assume_init()
}
}
}
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, Stderr, 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,
precision: Option<usize>,
separator: u8,
}
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,
precision: None,
separator: b' ',
}
}
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,
precision: None,
separator: b' ',
}
}
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(self.separator);
}
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;
}
pub fn set_precision(&mut self, precision: usize) {
self.precision = Some(precision);
}
pub fn reset_precision(&mut self) {
self.precision = None;
}
pub fn get_precision(&self) -> Option<usize> {
self.precision
}
pub fn separator(&self) -> u8 {
self.separator
}
pub fn set_separator(&mut self, separator: u8) {
self.separator = separator;
}
}
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(out
.separator); 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 random {
use crate::algo_lib::collections::slice_ext::indices::Indices;
use crate::algo_lib::numbers::num_traits::algebra::IntegerSemiRingWithSub;
use crate::algo_lib::numbers::num_traits::ord::MinMax;
use crate::algo_lib::numbers::num_traits::primitive::Primitive;
use std::cell::RefCell;
use std::ops::{RangeBounds, Rem};
use std::time::SystemTime;
const NN: usize = 312;
const MM: usize = 156;
const MATRIX_A: u64 = 0xB5026F5AA96619E9;
const UM: u64 = 0xFFFFFFFF80000000;
const LM: u64 = 0x7FFFFFFF;
const F: u64 = 6364136223846793005;
const MAG01: [u64; 2] = [0, MATRIX_A];
pub struct Random {
mt: [u64; NN],
index: usize,
}
impl Random {
pub fn new() -> Self {
Self::new_with_seed(
(SystemTime::UNIX_EPOCH.elapsed().unwrap().as_nanos() & 0xFFFFFFFFFFFFFFFF)
as u64,
)
}
pub fn new_with_seed(seed: u64) -> Self {
let mut res = Self { mt: [0u64; NN], index: NN };
res.mt[0] = seed;
for i in 1..NN {
res.mt[i] = F
.wrapping_mul(res.mt[i - 1] ^ (res.mt[i - 1] >> 62))
.wrapping_add(i as u64);
}
res
}
fn gen_impl(&mut self) -> u64 {
if self.index == NN {
for i in 0..(NN - MM) {
let x = (self.mt[i] & UM) | (self.mt[i + 1] & LM);
self.mt[i] = self.mt[i + MM] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
}
for i in (NN - MM)..(NN - 1) {
let x = (self.mt[i] & UM) | (self.mt[i + 1] & LM);
self.mt[i] = self.mt[i + MM - NN] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
}
let x = (self.mt[NN - 1] & UM) | (self.mt[0] & LM);
self.mt[NN - 1] = self.mt[MM - 1] ^ (x >> 1) ^ MAG01[(x & 1) as usize];
self.index = 0;
}
let mut x = self.mt[self.index];
self.index += 1;
x ^= (x >> 29) & 0x5555555555555555;
x ^= (x << 17) & 0x71D67FFFEDA60000;
x ^= (x << 37) & 0xFFF7EEE000000000;
x ^= x >> 43;
x
}
pub fn gen<T>(&mut self) -> T
where
u64: Primitive<T>,
{
self.gen_impl().to()
}
pub fn gen_u128(&mut self) -> u128 {
(self.gen_impl() as u128) << 64 | self.gen_impl() as u128
}
pub fn gen_i128(&mut self) -> i128 {
self.gen_u128() as i128
}
pub fn gen_bool(&mut self) -> bool {
(self.gen_impl() & 1) == 1
}
pub fn gen_bound<T: Rem<Output = T> + Primitive<u64>>(&mut self, n: T) -> T
where
u64: Primitive<T>,
{
(self.gen_impl() % n.to()).to()
}
pub fn gen_range<T: IntegerSemiRingWithSub + Primitive<u64> + MinMax>(
&mut self,
range: impl RangeBounds<T>,
) -> T
where
u64: Primitive<T>,
{
let f = match range.start_bound() {
std::ops::Bound::Included(&s) => s,
std::ops::Bound::Excluded(&s) => s + T::one(),
std::ops::Bound::Unbounded => T::min_val(),
};
let t = match range.end_bound() {
std::ops::Bound::Included(&e) => e,
std::ops::Bound::Excluded(&e) => e - T::one(),
std::ops::Bound::Unbounded => T::max_val(),
};
if f == T::min_val() && t == T::max_val() {
self.gen()
} else {
f + self.gen_bound(t - f + T::one())
}
}
}
thread_local! {
static RANDOM : RefCell < Random > = RefCell::new(Random::new());
}
pub fn gen<T>() -> T
where
u64: Primitive<T>,
{
RANDOM.with_borrow_mut(|r| r.gen())
}
pub fn gen_u128() -> u128 {
RANDOM.with_borrow_mut(|r| r.gen_u128())
}
pub fn gen_i128() -> i128 {
RANDOM.with_borrow_mut(|r| r.gen_i128())
}
pub fn gen_bool() -> bool {
RANDOM.with_borrow_mut(|r| r.gen_bool())
}
pub fn gen_bound<T: Rem<Output = T> + Primitive<u64>>(n: T) -> T
where
u64: Primitive<T>,
{
RANDOM.with_borrow_mut(|r| r.gen_bound(n))
}
pub fn gen_range<T: IntegerSemiRingWithSub + Primitive<u64> + MinMax>(
range: impl RangeBounds<T>,
) -> T
where
u64: Primitive<T>,
{
RANDOM.with_borrow_mut(|r| r.gen_range(range))
}
pub trait Shuffle {
fn shuffle(&mut self);
}
impl<T> Shuffle for [T] {
fn shuffle(&mut self) {
for i in self.indices() {
let at = gen_bound(i + 1);
self.swap(i, at);
}
}
}
}
pub mod recursive_function {
use std::marker::PhantomData;
macro_rules! recursive_function {
($name:ident, $trait:ident, ($($type:ident $arg:ident,)*)) => {
pub trait $trait <$($type,)* Output > { fn call(& mut self, $($arg : $type,)*) ->
Output; } pub struct $name < F, $($type,)* Output > where F : FnMut(& mut dyn
$trait <$($type,)* Output >, $($type,)*) -> Output, { f : std::cell::UnsafeCell <
F >, $($arg : PhantomData <$type >,)* phantom_output : PhantomData < Output >, }
impl < F, $($type,)* Output > $name < F, $($type,)* Output > where F : FnMut(&
mut dyn $trait <$($type,)* Output >, $($type,)*) -> Output, { pub fn new(f : F)
-> Self { Self { f : std::cell::UnsafeCell::new(f), $($arg :
Default::default(),)* phantom_output : Default::default(), } } } impl < F,
$($type,)* Output > $trait <$($type,)* Output > for $name < F, $($type,)* Output
> where F : FnMut(& mut dyn $trait <$($type,)* Output >, $($type,)*) -> Output, {
fn call(& mut self, $($arg : $type,)*) -> Output { unsafe { (* self.f.get())
(self, $($arg,)*) } } }
};
}
recursive_function!(RecursiveFunction0, Callable0, ());
recursive_function!(RecursiveFunction, Callable, (Arg arg,));
recursive_function!(RecursiveFunction2, Callable2, (Arg1 arg1, Arg2 arg2,));
recursive_function!(RecursiveFunction3, Callable3, (Arg1 arg1, Arg2 arg2, Arg3 arg3,));
recursive_function!(
RecursiveFunction4, Callable4, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4,)
);
recursive_function!(
RecursiveFunction5, Callable5, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5
arg5,)
);
recursive_function!(
RecursiveFunction6, Callable6, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5
arg5, Arg6 arg6,)
);
recursive_function!(
RecursiveFunction7, Callable7, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5
arg5, Arg6 arg6, Arg7 arg7,)
);
recursive_function!(
RecursiveFunction8, Callable8, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5
arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8,)
);
recursive_function!(
RecursiveFunction9, Callable9, (Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5
arg5, Arg6 arg6, Arg7 arg7, Arg8 arg8, Arg9 arg9,)
);
}
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> {
fn set_val(t: T);
}
#[macro_export]
macro_rules! dynamic_value {
($name:ident : $t:ty) => {
#[allow(non_upper_case_globals)] static mut $name : 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 { $name = Some(t); } } } impl $crate ::algo_lib::misc::value::Value <$t >
for $name { fn val() -> $t { unsafe { $name .unwrap() } } }
};
($name:ident : $t:ty = $val:expr) => {
dynamic_value!($name : $t); <$name as $crate
::algo_lib::misc::value::DynamicValue <$t >>::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, IntegerSemiRingWithSub, Zero,
};
use std::mem::swap;
pub fn extended_gcd<T: IntegerSemiRingWithSub + Copy>(a: T, b: T) -> (T, T, T) {
if a == T::zero() {
(b, T::zero(), T::one())
} else {
let (d, y, mut x) = extended_gcd(b % a, a);
x -= 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 fn remainder<T: IntegerSemiRingWithSub + Copy>(
a1: T,
n1: T,
a2: T,
n2: T,
) -> Option<T> {
let (d, m1, m2) = extended_gcd(n1, n2);
if (a2 - a1) % d != T::zero() {
return None;
}
let m = lcm(n1, n2);
Some(((a1 * m2) % n1 * n2 + (a2 * m1) % n2 * n1) % m)
}
}
pub mod mod_int {
use crate::algo_lib::collections::fx_hash_map::FxHashMap;
use crate::algo_lib::io::input::{Input, Readable};
use crate::algo_lib::io::output::{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, One, Zero};
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use crate::{value, when};
use std::fmt::{Display, Formatter};
use std::hash::Hash;
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
pub trait BaseModInt<T>: Field + Copy {
fn from(v: T) -> Self;
fn module() -> T;
fn value(&self) -> T;
}
macro_rules! mod_int {
($name:ident, $t:ty, $s:ty, $w:ty) => {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Default)] pub struct $name < V : Value
<$t >> { n : $t, phantom : PhantomData < V >, } impl < V : Value <$t >> $name < V
> { unsafe fn unchecked_new(n : $t) -> Self { debug_assert!(n < V::val()); Self {
n, phantom : Default::default(), } } unsafe fn maybe_subtract_mod(mut n : $t) ->
$t { debug_assert!(n < 2 * V::val()); if n >= V::val() { n -= V::val(); } n } }
impl < V : Value <$t >> $name < V > { pub fn new(n : $t) -> Self { unsafe {
Self::unchecked_new(n % (V::val())) } } pub fn new_signed(n : $s) -> Self {
unsafe { Self::unchecked_new(Self::maybe_subtract_mod((n % (V::val() as $s) +
V::val() as $s) as $t,)) } } pub fn val(& self) -> $t { self.n } } impl < V :
Value <$t >> $name < V > { pub fn log(& self, alpha : Self) -> $t { let mut base
= FxHashMap::default(); let mut exp = 0; 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 += 1; pow *=
alpha; inv *= alpha_inv; } let step = pow; let mut i = 1; loop { if let Some(b) =
base.get(& pow) { break exp * i + * b; } pow *= step; i += 1; } } } impl < V :
Value <$t >> $name < V > { pub fn new_from_wide(n : $w) -> Self { unsafe {
Self::unchecked_new(Self::maybe_subtract_mod((n % V::val() as $w + V::val() as
$w) as $t,)) } } } impl < V : Value <$t >> Invertible for $name < V > { type
Output = Self; fn inv(& self) -> Option < Self > { let (g, x, _) =
extended_gcd(self.n as $w, V::val() as $w); if g != 1 { None } else {
Some(Self::new_from_wide(x)) } } } impl < V : Value <$t >> BaseModInt <$t > for
$name < V > { fn from(v : $t) -> Self { Self::new(v) } fn module() -> $t {
V::val() } fn value(& self) -> $t { self.n } } impl < V : Value <$t >> From <$t >
for $name < V > { fn from(n : $t) -> Self { Self::new(n) } } impl < V : Value <$t
>> AddAssign for $name < V > { fn add_assign(& mut self, rhs : Self) { self.n =
unsafe { Self::maybe_subtract_mod(self.n + rhs.n) }; } } impl < V : Value <$t >>
Add for $name < V > { type Output = Self; fn add(mut self, rhs : Self) ->
Self::Output { self += rhs; self } } impl < V : Value <$t >> SubAssign for $name
< V > { fn sub_assign(& mut self, rhs : Self) { self.n = unsafe {
Self::maybe_subtract_mod(self.n + V::val() - rhs.n) }; } } impl < V : Value <$t
>> Sub for $name < V > { type Output = Self; fn sub(mut self, rhs : Self) ->
Self::Output { self -= rhs; self } } impl < V : Value <$t >> MulAssign for $name
< V > { fn mul_assign(& mut self, rhs : Self) { self.n = ((self.n as $w) * (rhs.n
as $w) % (V::val() as $w)) as $t; } } impl < V : Value <$t >> Mul for $name < V >
{ type Output = Self; fn mul(mut self, rhs : Self) -> Self::Output { self *= rhs;
self } } impl < V : Value <$t >> DivAssign for $name < V > {
#[allow(clippy::suspicious_op_assign_impl)] fn div_assign(& mut self, rhs : Self)
{ * self *= rhs.inv().unwrap(); } } impl < V : Value <$t >> Div for $name < V > {
type Output = Self; fn div(mut self, rhs : Self) -> Self::Output { self /= rhs;
self } } impl < V : Value <$t >> Neg for $name < V > { type Output = Self; fn
neg(mut self) -> Self::Output { if self.n != 0 { self.n = V::val() - self.n; }
self } } impl < V : Value <$t >> Display for $name < V > { fn fmt(& self, f : &
mut Formatter <'_ >) -> std::fmt::Result { <$t as Display >::fmt(& self.n, f) } }
impl < V : Value <$t >> Readable for $name < V > { fn read(input : & mut Input)
-> Self { Self::new(input.read()) } } impl < V : Value <$t >> Writable for $name
< V > { fn write(& self, output : & mut Output) { self.n.write(output); } } impl
< V : Value <$t >> Zero for $name < V > { fn zero() -> Self { unsafe {
Self::unchecked_new(0) } } } impl < V : Value <$t >> One for $name < V > { fn
one() -> Self { Self::new(1) } } impl < V : Value <$t >> std::fmt::Debug for
$name < V > { fn fmt(& self, f : & mut Formatter) -> std::fmt::Result { let max =
100; when! { self.n <= max => write!(f, "{}", self.n), self.n >= V::val() - max
=> write!(f, "-{}", V::val() - self.n), else => { for denominator in 1..max { for
num in 1..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);
} } } write!(f, "(?? {} ??)", self.n) }, } } } impl < V : Value <$t >> AsIndex
for $name < V > { fn from_index(idx : usize) -> Self { let v = idx as $w; if v >=
V::val() as $w { Self::new_from_wide(v) } else { unsafe { Self::unchecked_new(v
as $t) } } } fn to_index(self) -> usize { self.n.to_index() } }
};
}
mod_int!(ModInt, u32, i32, i64);
mod_int!(ModInt64, u64, i64, i128);
value!(Val7 : u32 = 1_000_000_007);
pub type ModInt7 = ModInt<Val7>;
value!(Val9 : u32 = 1_000_000_009);
pub type ModInt9 = ModInt<Val9>;
value!(ValF : u32 = 998_244_353);
pub type ModIntF = ModInt<ValF>;
}
pub mod num_traits {
pub mod algebra {
use crate::algo_lib::numbers::num_traits::invertible::Invertible;
use std::ops::{
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, 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 bit_ops {
use crate::algo_lib::numbers::num_traits::algebra::{One, Zero};
use std::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, RangeInclusive,
Shl, Sub,
};
use std::ops::{ShlAssign, Shr, ShrAssign};
pub trait BitOps: Copy + BitAnd<
Output = Self,
> + BitAndAssign + BitOr<
Output = Self,
> + BitOrAssign + BitXor<
Output = Self,
> + BitXorAssign + Not<
Output = Self,
> + Shl<
usize,
Output = Self,
> + ShlAssign<
usize,
> + Shr<usize, Output = Self> + ShrAssign<usize> + Zero + One + PartialEq {
#[inline]
fn bit(at: usize) -> Self {
Self::one() << at
}
#[inline]
fn is_set(&self, at: usize) -> bool {
(*self >> at & Self::one()) == Self::one()
}
#[inline]
fn set_bit(&mut self, at: usize) {
*self |= Self::bit(at);
}
#[inline]
fn unset_bit(&mut self, at: usize) {
*self &= !Self::bit(at);
}
#[must_use]
#[inline]
fn with_bit(mut self, at: usize) -> Self {
self.set_bit(at);
self
}
#[must_use]
#[inline]
fn without_bit(mut self, at: usize) -> Self {
self.unset_bit(at);
self
}
#[inline]
fn flip_bit(&mut self, at: usize) {
*self ^= Self::bit(at);
}
#[must_use]
#[inline]
fn flipped_bit(mut self, at: usize) -> Self {
self.flip_bit(at);
self
}
fn all_bits(n: usize) -> Self {
let mut res = Self::zero();
for i in 0..n {
res.set_bit(i);
}
res
}
fn iter_all(n: usize) -> RangeInclusive<Self> {
Self::zero()..=Self::all_bits(n)
}
}
pub struct BitIter<T> {
cur: T,
all: T,
ended: bool,
}
impl<T: Copy> BitIter<T> {
pub fn new(all: T) -> Self {
Self {
cur: all,
all,
ended: false,
}
}
}
impl<T: BitOps + Sub<Output = T>> Iterator for BitIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.ended {
return None;
}
let res = self.cur;
if self.cur == T::zero() {
self.ended = true;
} else {
self.cur = (self.cur - T::one()) & self.all;
}
Some(res)
}
}
impl<
T: Copy + BitAnd<Output = Self> + BitAndAssign + BitOr<Output = Self> + BitOrAssign
+ BitXor<Output = Self> + BitXorAssign + Not<Output = Self>
+ Shl<usize, Output = Self> + ShlAssign<usize> + Shr<usize, Output = Self>
+ ShrAssign<usize> + One + Zero + PartialEq,
> BitOps for T {}
pub trait Bits: BitOps {
fn bits() -> u32;
}
macro_rules! bits_integer_impl {
($($t:ident $bits:expr),+) => {
$(impl Bits for $t { fn bits() -> u32 { $bits } })+
};
}
bits_integer_impl!(
i128 128, i64 64, i32 32, i16 16, i8 8, isize 64, u128 128, u64 64, u32 32, u16 16,
u8 8, usize 64
);
}
pub mod invertible {
pub trait Invertible {
type Output;
fn inv(&self) -> Option<Self::Output>;
}
}
pub mod ord {
pub trait MinMax: PartialOrd {
fn min_val() -> Self;
fn max_val() -> Self;
}
macro_rules! min_max_integer_impl {
($($t:ident)+) => {
$(impl MinMax for $t { fn min_val() -> Self { std::$t ::MIN } fn max_val() ->
Self { std::$t ::MAX } })+
};
}
min_max_integer_impl!(i128 i64 i32 i16 i8 isize u128 u64 u32 u16 u8 usize);
}
pub mod primitive {
pub trait Primitive<T>: Copy {
fn to(self) -> T;
fn from(t: T) -> Self;
}
macro_rules! primitive_one {
($t:ident, $($u:ident)+) => {
$(impl Primitive <$u > for $t { fn to(self) -> $u { self as $u } fn from(t : $u)
-> Self { t as $t } })+
};
}
macro_rules! primitive {
($($t:ident)+) => {
$(primitive_one!($t, u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);)+
};
}
primitive!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
}
}
pub mod number_ext {
use crate::algo_lib::numbers::num_traits::algebra::{
IntegerSemiRing, 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 fn num_digs<S: IntegerSemiRing + AsIndex + Copy>(mut copy: S) -> usize {
let ten = S::from_index(10);
let mut res = 0;
while copy != S::zero() {
copy /= ten;
res += 1;
}
res
}
pub fn sum_digs<S: IntegerSemiRing + AsIndex + Copy>(mut copy: S) -> S {
let ten = S::from_index(10);
let mut res = S::zero();
while copy != S::zero() {
res += copy % ten;
copy /= ten;
}
res
}
pub fn digits<S: IntegerSemiRing + AsIndex + Copy>(
mut copy: S,
) -> impl Iterator<Item = S> {
let ten = S::from_index(10);
std::iter::from_fn(move || {
if copy == S::zero() {
None
} else {
let res = copy % ten;
copy /= ten;
Some(res)
}
})
}
pub trait Square {
fn square(self) -> Self;
}
impl<T: Mul<Output = T> + Copy> Square for T {
fn square(self) -> Self {
self * self
}
}
}
pub mod primes {
pub mod factorize {
use crate::algo_lib::collections::vec_ext::sorted::Sorted;
use crate::algo_lib::misc::recursive_function::{Callable2, RecursiveFunction2};
use crate::algo_lib::numbers::num_traits::algebra::MultiplicationMonoid;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
use crate::algo_lib::numbers::num_traits::primitive::Primitive;
use crate::algo_lib::numbers::primes::prime::find_divisor;
use crate::algo_lib::numbers::primes::sieve::divisor_table;
use std::cmp::Ordering;
pub trait Factorize {
fn prime_divisors(self) -> Vec<(u64, usize)>;
fn divisors(self) -> Vec<u64>;
fn max_power(self, p: Self) -> usize;
}
impl<T: Primitive<u64>> Factorize for T {
fn prime_divisors(self) -> Vec<(u64, usize)> {
let n = self.to();
assert!(n >= 1);
if n == 1 {
return Vec::new();
}
let d = if n > 100 {
find_divisor(n)
} else {
let mut res = n;
let mut i = 2;
while i * i <= n {
if n % i == 0 {
res = i;
break;
}
i += 1;
}
res
};
if d == n {
return vec![(d, 1)];
}
let left = d.prime_divisors();
let right = (n / d).prime_divisors();
let mut res = Vec::new();
let mut i = 0;
let mut j = 0;
while i < left.len() && j < right.len() {
match left[i].0.cmp(&right[j].0) {
Ordering::Less => {
res.push(left[i]);
i += 1;
}
Ordering::Equal => {
res.push((left[i].0, left[i].1 + right[j].1));
i += 1;
j += 1;
}
Ordering::Greater => {
res.push(right[j]);
j += 1;
}
}
}
res.extend_from_slice(&left[i..]);
res.extend_from_slice(&right[j..]);
res
}
fn divisors(self) -> Vec<u64> {
let pd = self.prime_divisors();
let mut res = Vec::new();
let mut rec = RecursiveFunction2::new(|f, mut d: u64, step: usize| {
if step == pd.len() {
res.push(d);
} else {
let (p, e) = pd[step];
for i in 0..=e {
f.call(d, step + 1);
if i < e {
d *= p;
}
}
}
});
rec.call(1, 0);
res.sorted()
}
fn max_power(self, p: Self) -> usize {
let mut res = 0;
let mut cur = self.to();
assert!(cur >= 1);
let p = p.to();
assert!(p >= 2);
while cur % p == 0 {
cur /= p;
res += 1;
}
res
}
}
pub fn all_divisors<T: AsIndex + PartialEq + Copy + MultiplicationMonoid + Ord>(
n: usize,
sorted: bool,
) -> Vec<Vec<T>> {
let d: Vec<T> = divisor_table(n);
let mut res = Vec::with_capacity(n);
if n > 0 {
res.push(Vec::new());
}
if n > 1 {
res.push(vec![T::from_index(1)]);
}
for (i, p) in d.into_iter().enumerate().skip(2) {
let mut q = 0;
let mut c = i;
while c % p.to_index() == 0 {
c /= p.to_index();
q += 1;
}
let mut cur = Vec::with_capacity(res[c].len() * (q + 1));
let mut by = T::from_index(1);
for j in 0..=q {
cur.extend(res[c].iter().map(|&x| x * by));
if j != q {
by *= p;
}
}
if sorted {
cur.sort();
}
res.push(cur);
}
res
}
}
pub mod prime {
use crate::algo_lib::misc::random::{gen_bound, gen_range};
use crate::algo_lib::numbers::gcd::gcd;
use crate::algo_lib::numbers::mod_int::ModInt64;
use crate::algo_lib::numbers::num_traits::algebra::{One, Zero};
use crate::algo_lib::numbers::num_traits::primitive::Primitive;
use crate::algo_lib::numbers::number_ext::Power;
use crate::{dynamic_value, when};
pub fn is_prime(n: impl Primitive<u64>) -> bool {
let n = n.to();
if n <= 1 {
return false;
}
let mut s = 0;
let mut d = n - 1;
while d % 2 == 0 {
s += 1;
d >>= 1;
}
if s == 0 {
return n == 2;
}
dynamic_value!(IsPrimeModule : u64 = n);
type Mod = ModInt64<IsPrimeModule>;
for _ in 0..20 {
let a = Mod::new(gen_bound(n));
if a == Mod::zero() {
continue;
}
if a.power(d) == Mod::one() {
continue;
}
let mut dd = d;
let mut good = true;
for _ in 0..s {
if a.power(dd) == -Mod::one() {
good = false;
break;
}
dd *= 2;
}
if good {
return false;
}
}
true
}
pub fn next_prime(mut n: u64) -> u64 {
if n <= 2 {
return 2;
}
n += 1 - (n & 1);
while !is_prime(n) {
n += 2;
}
n
}
fn brent(n: u64, x0: u64, c: u64) -> u64 {
dynamic_value!(ModVal : u64 = n);
type Mod = ModInt64<ModVal>;
let mut x = Mod::new(x0);
let c = Mod::new(c);
let mut g = 1;
let mut q = Mod::one();
let mut xs = Mod::zero();
let mut y = Mod::zero();
let m = 128i64;
let mut l = 1;
while g == 1 {
y = x;
for _ in 1..l {
x = x * x + c;
}
let mut k = 0;
while k < l && g == 1 {
xs = x;
for _ in 0..m.min(l - k) {
x = x * x + c;
q *= y - x;
}
g = gcd(q.val(), n);
k += m;
}
l *= 2;
}
if g == n {
loop {
xs = xs * xs + c;
g = gcd((xs - y).val(), n);
if g != 1 {
break;
}
}
}
g
}
pub fn find_divisor(n: u64) -> u64 {
when! {
n == 1 => 1, n % 2 == 0 => 2, is_prime(n) => n, else => { loop { let res =
brent(n, gen_range(2..n), gen_range(1..n),); if res != n { return res; } } },
}
}
}
pub mod sieve {
use crate::algo_lib::collections::bit_set::BitSet;
use crate::algo_lib::numbers::num_traits::as_index::AsIndex;
pub fn primality_table(n: usize) -> BitSet {
let mut res = BitSet::new(n);
res.fill(true);
if n > 0 {
res.unset(0);
}
if n > 1 {
res.unset(1);
}
let mut i = 2;
while i * i < n {
if res[i] {
for j in ((i * i)..n).step_by(i) {
res.unset(j);
}
}
i += 1;
}
res
}
pub fn primes<T: AsIndex>(n: usize) -> Vec<T> {
primality_table(n).into_iter().map(|i| T::from_index(i)).collect()
}
pub fn divisor_table<T: AsIndex + PartialEq>(n: usize) -> Vec<T> {
let mut res: Vec<_> = (0..n).map(|i| T::from_index(i)).collect();
let mut i = 2;
while i * i < n {
if res[i] == T::from_index(i) {
for j in ((i * i)..n).step_by(i) {
res[j] = T::from_index(i);
}
}
i += 1;
}
res
}
}
}
}
}