QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#679906 | #9530. A Game On Tree | ucup-team296# | AC ✓ | 151ms | 21860kb | Rust | 52.3kb | 2024-10-26 19:11:03 | 2024-10-26 19:11:04 |
Judging History
answer
// https://contest.ucup.ac/contest/1817/problem/9530
pub mod solution {
//{"name":"L. A Game On Tree","group":"Universal Cup - The 3rd Universal Cup. Stage 14: Harbin","url":"https://contest.ucup.ac/contest/1817/problem/9530","interactive":false,"timeLimit":1000,"tests":[{"input":"2\n3\n1 2\n2 3\n5\n1 2\n1 5\n3 2\n4 2\n","output":"443664158\n918384806\n"}],"testType":"single","input":{"type":"stdin","fileName":null,"pattern":null},"output":{"type":"stdout","fileName":null,"pattern":null},"languages":{"java":{"taskClass":"LAGameOnTree"}}}
use crate::algo_lib::collections::vec_ext::inc_dec::IncDec;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use crate::algo_lib::graph::graph::Graph;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::misc::recursive_function::Callable2;
use crate::algo_lib::misc::recursive_function::RecursiveFunction2;
use crate::algo_lib::misc::test_type::TaskType;
use crate::algo_lib::misc::test_type::TestType;
use crate::algo_lib::numbers::mod_int::ModIntF;
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;
type PreCalc = ();
fn solve(input: &mut Input, out: &mut Output, _test_case: usize, _data: &mut PreCalc) {
let n = input.read_size();
let edges = input.read_size_pair_vec(n - 1).dec();
let graph = Graph::from_biedges(n, &edges);
type Mod = ModIntF;
struct State {
sum: Mod,
sum_linear: Mod,
sum_square: Mod,
dangling_one: Mod,
dangling_ans: Mod,
ans: Mod,
}
impl State {
fn single() -> Self {
Self {
sum: Mod::one(),
sum_linear: Mod::zero(),
sum_square: Mod::zero(),
dangling_one: Mod::zero(),
dangling_ans: Mod::zero(),
ans: Mod::zero(),
}
}
fn add_root(&mut self) {
self.ans += self.sum_square * Mod::new(2) + self.dangling_ans * Mod::new(2);
self.dangling_ans += self.sum_square;
self.dangling_one += Mod::one();
self.sum_square += self.sum_linear * Mod::new(2) + self.sum;
self.sum_linear += self.sum;
self.sum += self.dangling_one * Mod::new(2);
}
fn join(mut left: Self, right: Self) -> Self {
left.ans = Mod::new_from_wide(
left.ans.val() as i64
+ right.ans.val() as i64
+ left.sum_square.val() as i64 * right.sum.val() as i64
+ 2 * left.sum_linear.val() as i64 * right.sum_linear.val() as i64
+ left.sum.val() as i64 * right.sum_square.val() as i64
+ 2 * left.dangling_one.val() as i64 * right.dangling_ans.val() as i64
+ 2 * right.dangling_one.val() as i64 * left.dangling_ans.val() as i64,
);
// left.ans += right.ans;
// left.ans += left.sum_square * right.sum
// + Mod::new(2) * left.sum_linear * right.sum_linear
// + left.sum * right.sum_square;
// left.ans += (left.dangling_one * right.dangling_ans
// + right.dangling_one * left.dangling_ans)
// * Mod::new(2);
left.dangling_ans = Mod::new_from_wide(
left.dangling_ans.val() as i64
+ right.dangling_ans.val() as i64
+ left.dangling_one.val() as i64 * right.sum_square.val() as i64
+ right.dangling_one.val() as i64 * left.sum_square.val() as i64,
);
// left.dangling_ans += right.dangling_ans;
// left.dangling_ans +=
// left.dangling_one * right.sum_square + right.dangling_one * left.sum_square;
left.sum = Mod::new_from_wide(
left.sum.val() as i64
+ right.sum.val() as i64
+ left.dangling_one.val() as i64 * right.dangling_one.val() as i64 * 2,
);
// left.sum += left.dangling_one * right.dangling_one * Mod::new(2);
left.dangling_one += right.dangling_one;
// left.sum += right.sum;
left.sum_linear += right.sum_linear;
left.sum_square += right.sum_square;
left
}
}
let mut dfs = RecursiveFunction2::new(|f, vert: usize, prev: usize| -> State {
let mut state = State::single();
for e in &graph[vert] {
if e.to() == prev {
continue;
}
let mut call = f.call(e.to(), vert);
call.add_root();
state = State::join(state, call);
}
state
});
let paths = Mod::from_index(n) * Mod::from_index(n - 1) / Mod::new(2);
let ans = dfs.call(0, n).ans / paths / paths;
out.print_line(ans);
}
pub static TEST_TYPE: TestType = TestType::MultiNumber;
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 dsu {
use crate::algo_lib::collections::iter_ext::collect::IterCollect;
use crate::algo_lib::collections::slice_ext::bounds::Bounds;
use crate::algo_lib::collections::slice_ext::legacy_fill::LegacyFill;
use std::cell::Cell;
#[derive(Clone)]
pub struct DSU {
id: Vec<Cell<u32>>,
size: Vec<u32>,
count: usize,
}
impl DSU {
pub fn new(n: usize) -> Self {
Self {
id: (0..n).map(|i| Cell::new(i as u32)).collect_vec(),
size: vec![1; n],
count: n,
}
}
pub fn size(&self, i: usize) -> usize {
self.size[self.get(i)] as usize
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.id.len()
}
pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
self.id.iter().enumerate().filter_map(|(i, id)| {
if (i as u32) == id.get() {
Some(i)
} else {
None
}
})
}
pub fn set_count(&self) -> usize {
self.count
}
pub fn join(&mut self, mut a: usize, mut b: usize) -> bool {
a = self.get(a);
b = self.get(b);
if a == b {
false
} else {
self.size[a] += self.size[b];
self.id[b].replace(a as u32);
self.count -= 1;
true
}
}
pub fn get(&self, i: usize) -> usize {
if self.id[i].get() != i as u32 {
let res = self.get(self.id[i].get() as usize);
self.id[i].replace(res as u32);
}
self.id[i].get() as usize
}
pub fn clear(&mut self) {
self.count = self.id.len();
self.size.legacy_fill(1);
self.id.iter().enumerate().for_each(|(i, id)| {
id.replace(i as u32);
});
}
pub fn parts(&self) -> Vec<Vec<usize>> {
let roots = self.iter().collect_vec();
let mut res = vec![Vec::new(); roots.len()];
for i in 0..self.id.len() {
res[roots.as_slice().bin_search(&self.get(i)).unwrap()].push(i);
}
res
}
}
}
pub mod iter_ext {
pub mod collect {
pub trait IterCollect<T>: Iterator<Item = T> + Sized {
fn collect_vec(self) -> Vec<T> {
self.collect()
}
}
impl<T, I: Iterator<Item = T> + Sized> IterCollect<T> for I {}
}
}
pub mod slice_ext {
pub mod bounds {
pub trait Bounds<T: PartialOrd> {
fn lower_bound(&self, el: &T) -> usize;
fn upper_bound(&self, el: &T) -> usize;
fn bin_search(&self, el: &T) -> Option<usize>;
fn more(&self, el: &T) -> usize;
fn more_or_eq(&self, el: &T) -> usize;
fn less(&self, el: &T) -> usize;
fn less_or_eq(&self, el: &T) -> usize;
}
impl<T: PartialOrd> Bounds<T> for [T] {
fn lower_bound(&self, el: &T) -> usize {
let mut left = 0;
let mut right = self.len();
while left < right {
let mid = left + ((right - left) >> 1);
if &self[mid] < el {
left = mid + 1;
} else {
right = mid;
}
}
left
}
fn upper_bound(&self, el: &T) -> usize {
let mut left = 0;
let mut right = self.len();
while left < right {
let mid = left + ((right - left) >> 1);
if &self[mid] <= el {
left = mid + 1;
} else {
right = mid;
}
}
left
}
fn bin_search(&self, el: &T) -> Option<usize> {
let at = self.lower_bound(el);
if at == self.len() || &self[at] != el {
None
} else {
Some(at)
}
}
fn more(&self, el: &T) -> usize {
self.len() - self.upper_bound(el)
}
fn more_or_eq(&self, el: &T) -> usize {
self.len() - self.lower_bound(el)
}
fn less(&self, el: &T) -> usize {
self.lower_bound(el)
}
fn less_or_eq(&self, el: &T) -> usize {
self.upper_bound(el)
}
}
}
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 inc_dec {
use crate::algo_lib::numbers::num_traits::algebra::AdditionMonoidWithSub;
use crate::algo_lib::numbers::num_traits::algebra::One;
pub trait IncDec {
#[must_use]
fn inc(self) -> Self;
#[must_use]
fn dec(self) -> Self;
}
impl<T: AdditionMonoidWithSub + One> IncDec for T {
fn inc(self) -> Self {
self + T::one()
}
fn dec(self) -> Self {
self - T::one()
}
}
impl<T: AdditionMonoidWithSub + One> IncDec for Vec<T> {
fn inc(mut self) -> Self {
self.iter_mut().for_each(|i| *i += T::one());
self
}
fn dec(mut self) -> Self {
self.iter_mut().for_each(|i| *i -= T::one());
self
}
}
impl<T: AdditionMonoidWithSub + One, U: AdditionMonoidWithSub + One> IncDec for Vec<(T, U)> {
fn inc(mut self) -> Self {
self.iter_mut().for_each(|(i, j)| {
*i += T::one();
*j += U::one();
});
self
}
fn dec(mut self) -> Self {
self.iter_mut().for_each(|(i, j)| {
*i -= T::one();
*j -= U::one();
});
self
}
}
impl<T: AdditionMonoidWithSub + One, U: AdditionMonoidWithSub + One, V> IncDec for Vec<(T, U, V)> {
fn inc(mut self) -> Self {
self.iter_mut().for_each(|(i, j, _)| {
*i += T::one();
*j += U::one();
});
self
}
fn dec(mut self) -> Self {
self.iter_mut().for_each(|(i, j, _)| {
*i -= T::one();
*j -= U::one();
});
self
}
}
impl<T: AdditionMonoidWithSub + One, U: AdditionMonoidWithSub + One, V, W> IncDec
for Vec<(T, U, V, W)>
{
fn inc(mut self) -> Self {
self.iter_mut().for_each(|(i, j, ..)| {
*i += T::one();
*j += U::one();
});
self
}
fn dec(mut self) -> Self {
self.iter_mut().for_each(|(i, j, ..)| {
*i -= T::one();
*j -= U::one();
});
self
}
}
impl<T: AdditionMonoidWithSub + One, U: AdditionMonoidWithSub + One, V, W, X> IncDec
for Vec<(T, U, V, W, X)>
{
fn inc(mut self) -> Self {
self.iter_mut().for_each(|(i, j, ..)| {
*i += T::one();
*j += U::one();
});
self
}
fn dec(mut self) -> Self {
self.iter_mut().for_each(|(i, j, ..)| {
*i -= T::one();
*j -= U::one();
});
self
}
}
impl<T: AdditionMonoidWithSub + One, U: AdditionMonoidWithSub + One> IncDec for (T, U) {
fn inc(mut self) -> Self {
self.0 += T::one();
self.1 += U::one();
self
}
fn dec(mut self) -> Self {
self.0 -= T::one();
self.1 -= U::one();
self
}
}
}
}
}
pub mod graph {
pub mod edges {
pub mod bi_edge {
use crate::algo_lib::graph::edges::bi_edge_trait::BiEdgeTrait;
use crate::algo_lib::graph::edges::edge_id::EdgeId;
use crate::algo_lib::graph::edges::edge_id::NoId;
use crate::algo_lib::graph::edges::edge_id::WithId;
use crate::algo_lib::graph::edges::edge_trait::BidirectionalEdgeTrait;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
#[derive(Clone)]
pub struct BiEdgeRaw<Id: EdgeId, P> {
to: u32,
id: Id,
payload: P,
}
impl<Id: EdgeId> BiEdgeRaw<Id, ()> {
pub fn new(from: usize, to: usize) -> (usize, Self) {
(
from,
Self {
to: to as u32,
id: Id::new(),
payload: (),
},
)
}
}
impl<Id: EdgeId, P> BiEdgeRaw<Id, P> {
pub fn with_payload(from: usize, to: usize, payload: P) -> (usize, Self) {
(from, Self::with_payload_impl(to, payload))
}
fn with_payload_impl(to: usize, payload: P) -> BiEdgeRaw<Id, P> {
Self {
to: to as u32,
id: Id::new(),
payload,
}
}
}
impl<Id: EdgeId, P: Clone> BidirectionalEdgeTrait for BiEdgeRaw<Id, P> {}
impl<Id: EdgeId, P: Clone> EdgeTrait for BiEdgeRaw<Id, P> {
type Payload = P;
const REVERSABLE: bool = true;
fn to(&self) -> usize {
self.to as usize
}
fn id(&self) -> usize {
self.id.id()
}
fn set_id(&mut self, id: usize) {
self.id.set_id(id);
}
fn reverse_id(&self) -> usize {
panic!("no reverse id")
}
fn set_reverse_id(&mut self, _: usize) {}
fn reverse_edge(&self, from: usize) -> Self {
Self::with_payload_impl(from, self.payload.clone())
}
fn payload(&self) -> &P {
&self.payload
}
}
impl<Id: EdgeId, P: Clone> BiEdgeTrait for BiEdgeRaw<Id, P> {}
pub type BiEdge<P> = BiEdgeRaw<NoId, P>;
pub type BiEdgeWithId<P> = BiEdgeRaw<WithId, P>;
}
pub mod bi_edge_trait {
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
pub trait BiEdgeTrait: EdgeTrait {}
}
pub mod edge {
use crate::algo_lib::graph::edges::edge_id::EdgeId;
use crate::algo_lib::graph::edges::edge_id::NoId;
use crate::algo_lib::graph::edges::edge_id::WithId;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
#[derive(Clone)]
pub struct EdgeRaw<Id: EdgeId, P> {
to: u32,
id: Id,
payload: P,
}
impl<Id: EdgeId> EdgeRaw<Id, ()> {
pub fn new(from: usize, to: usize) -> (usize, Self) {
(
from,
Self {
to: to as u32,
id: Id::new(),
payload: (),
},
)
}
}
impl<Id: EdgeId, P> EdgeRaw<Id, P> {
pub fn with_payload(from: usize, to: usize, payload: P) -> (usize, Self) {
(from, Self::with_payload_impl(to, payload))
}
fn with_payload_impl(to: usize, payload: P) -> Self {
Self {
to: to as u32,
id: Id::new(),
payload,
}
}
}
impl<Id: EdgeId, P: Clone> EdgeTrait for EdgeRaw<Id, P> {
type Payload = P;
const REVERSABLE: bool = false;
fn to(&self) -> usize {
self.to as usize
}
fn id(&self) -> usize {
self.id.id()
}
fn set_id(&mut self, id: usize) {
self.id.set_id(id);
}
fn reverse_id(&self) -> usize {
panic!("no reverse")
}
fn set_reverse_id(&mut self, _: usize) {
panic!("no reverse")
}
fn reverse_edge(&self, _: usize) -> Self {
panic!("no reverse")
}
fn payload(&self) -> &P {
&self.payload
}
}
pub type Edge<P> = EdgeRaw<NoId, P>;
pub type EdgeWithId<P> = EdgeRaw<WithId, P>;
}
pub mod edge_id {
pub trait EdgeId: Clone {
fn new() -> Self;
fn id(&self) -> usize;
fn set_id(&mut self, id: usize);
}
#[derive(Clone)]
pub struct WithId {
id: u32,
}
impl EdgeId for WithId {
fn new() -> Self {
Self { id: 0 }
}
fn id(&self) -> usize {
self.id as usize
}
fn set_id(&mut self, id: usize) {
self.id = id as u32;
}
}
#[derive(Clone)]
pub struct NoId {}
impl EdgeId for NoId {
fn new() -> Self {
Self {}
}
fn id(&self) -> usize {
panic!("Id called on no id")
}
fn set_id(&mut self, _: usize) {}
}
}
pub mod edge_trait {
pub trait EdgeTrait: Clone {
type Payload;
const REVERSABLE: bool;
fn to(&self) -> usize;
fn id(&self) -> usize;
fn set_id(&mut self, id: usize);
fn reverse_id(&self) -> usize;
fn set_reverse_id(&mut self, reverse_id: usize);
#[must_use]
fn reverse_edge(&self, from: usize) -> Self;
fn payload(&self) -> &Self::Payload;
}
pub trait BidirectionalEdgeTrait: EdgeTrait {}
}
}
pub mod graph {
use crate::algo_lib::collections::dsu::DSU;
use crate::algo_lib::graph::edges::bi_edge::BiEdge;
use crate::algo_lib::graph::edges::edge::Edge;
use crate::algo_lib::graph::edges::edge_trait::BidirectionalEdgeTrait;
use crate::algo_lib::graph::edges::edge_trait::EdgeTrait;
use std::ops::Index;
use std::ops::IndexMut;
#[derive(Clone)]
pub struct Graph<E: EdgeTrait> {
pub(super) edges: Vec<Vec<E>>,
edge_count: usize,
}
impl<E: EdgeTrait> Graph<E> {
pub fn new(vertex_count: usize) -> Self {
Self {
edges: vec![Vec::new(); vertex_count],
edge_count: 0,
}
}
pub fn add_edge(&mut self, (from, mut edge): (usize, E)) -> usize {
let to = edge.to();
assert!(to < self.edges.len());
let direct_id = self.edges[from].len();
edge.set_id(self.edge_count);
self.edges[from].push(edge);
if E::REVERSABLE {
let rev_id = self.edges[to].len();
self.edges[from][direct_id].set_reverse_id(rev_id);
let mut rev_edge = self.edges[from][direct_id].reverse_edge(from);
rev_edge.set_id(self.edge_count);
rev_edge.set_reverse_id(direct_id);
self.edges[to].push(rev_edge);
}
self.edge_count += 1;
direct_id
}
pub fn add_vertices(&mut self, cnt: usize) {
self.edges.resize(self.edges.len() + cnt, Vec::new());
}
pub fn clear(&mut self) {
self.edge_count = 0;
for ve in self.edges.iter_mut() {
ve.clear();
}
}
pub fn vertex_count(&self) -> usize {
self.edges.len()
}
pub fn edge_count(&self) -> usize {
self.edge_count
}
pub fn degrees(&self) -> Vec<usize> {
self.edges.iter().map(|v| v.len()).collect()
}
}
impl<E: BidirectionalEdgeTrait> Graph<E> {
pub fn is_tree(&self) -> bool {
if self.edge_count + 1 != self.vertex_count() {
false
} else {
self.is_connected()
}
}
pub fn is_forest(&self) -> bool {
let mut dsu = DSU::new(self.vertex_count());
for i in 0..self.vertex_count() {
for e in self[i].iter() {
if i <= e.to() && !dsu.join(i, e.to()) {
return false;
}
}
}
true
}
pub fn is_connected(&self) -> bool {
let mut dsu = DSU::new(self.vertex_count());
for i in 0..self.vertex_count() {
for e in self[i].iter() {
dsu.join(i, e.to());
}
}
dsu.set_count() == 1
}
}
impl<E: EdgeTrait> Index<usize> for Graph<E> {
type Output = [E];
fn index(&self, index: usize) -> &Self::Output {
&self.edges[index]
}
}
impl<E: EdgeTrait> IndexMut<usize> for Graph<E> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.edges[index]
}
}
impl Graph<Edge<()>> {
pub fn from_edges(n: usize, edges: &[(usize, usize)]) -> Self {
let mut graph = Self::new(n);
for &(from, to) in edges {
graph.add_edge(Edge::new(from, to));
}
graph
}
}
impl<P: Clone> Graph<Edge<P>> {
pub fn from_edges_with_payload(n: usize, edges: &[(usize, usize, P)]) -> Self {
let mut graph = Self::new(n);
for (from, to, p) in edges.iter() {
graph.add_edge(Edge::with_payload(*from, *to, p.clone()));
}
graph
}
}
impl Graph<BiEdge<()>> {
pub fn from_biedges(n: usize, edges: &[(usize, usize)]) -> Self {
let mut graph = Self::new(n);
for &(from, to) in edges {
graph.add_edge(BiEdge::new(from, to));
}
graph
}
}
impl<P: Clone> Graph<BiEdge<P>> {
pub fn from_biedges_with_payload(n: usize, edges: &[(usize, usize, P)]) -> Self {
let mut graph = Self::new(n);
for (from, to, p) in edges.iter() {
graph.add_edge(BiEdge::with_payload(*from, *to, p.clone()));
}
graph
}
}
}
}
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 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> {
//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 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);
}
}
}
}
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);
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 2144kb
input:
2 3 1 2 2 3 5 1 2 1 5 3 2 4 2
output:
443664158 918384806
result:
ok 2 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 2140kb
input:
1000 7 3 6 4 3 5 3 2 6 1 4 7 1 12 5 7 10 7 2 10 11 2 1 7 8 1 4 2 9 11 6 9 12 11 3 5 6 2 5 1 2 4 5 6 4 3 6 5 2 5 1 5 4 5 3 2 8 1 8 2 8 4 2 6 1 5 6 7 6 3 8 8 3 8 7 3 4 8 6 4 2 7 5 2 1 4 4 3 1 4 3 2 1 6 5 1 6 1 2 5 3 5 4 2 12 8 11 5 11 12 8 3 12 6 12 2 3 4 6 10 11 1 5 9 5 7 5 9 6 1 7 6 4 7 8 7 5 4 9 6 ...
output:
948445317 468414020 550143557 918384806 711758412 487662742 776412276 869581749 240852807 765628773 211048577 887328316 890334966 940494682 760637552 908032643 592850815 584006902 908525604 221832080 433351719 56023919 867301808 183319566 698771049 366957926 449579681 599710576 310564911 286902823 3...
result:
ok 1000 lines
Test #3:
score: 0
Accepted
time: 9ms
memory: 2184kb
input:
1000 94 59 1 33 59 73 1 6 33 83 59 4 59 20 59 61 6 39 1 76 73 71 6 44 39 9 71 24 4 87 9 57 83 2 9 81 71 82 20 90 2 85 39 12 9 30 83 66 30 53 9 47 9 36 44 43 53 29 12 31 53 64 81 38 31 84 82 77 38 23 71 93 84 78 83 58 31 68 90 42 1 55 64 13 78 70 78 62 24 19 55 92 87 14 57 10 84 65 81 63 6 75 36 91 1...
output:
508107725 996793960 201633249 335988372 842755864 460619380 342223697 207523414 429241811 391691799 542977964 786416604 454278948 685531402 25914978 440729774 228518323 679471537 82764520 554190841 432505337 143444089 189106586 337234245 61954935 905141094 532919674 703954588 185671863 942858630 692...
result:
ok 1000 lines
Test #4:
score: 0
Accepted
time: 146ms
memory: 21360kb
input:
10000 8 1 4 3 1 5 1 7 3 8 4 6 8 2 7 8 2 6 4 6 5 6 8 5 7 6 3 5 1 7 8 8 5 6 5 2 5 7 2 1 6 3 1 4 8 9 8 6 9 8 3 6 1 8 5 9 2 8 4 3 7 9 8 8 6 3 6 5 8 1 6 4 3 7 6 2 6 9 9 5 7 5 2 7 8 7 4 9 3 7 6 3 1 4 8 1 4 5 1 6 5 3 4 8 4 7 8 2 5 9 1 8 6 1 2 1 3 8 5 3 9 8 7 8 4 8 9 4 9 2 9 1 2 3 4 5 2 6 9 8 3 7 2 8 1 2 8 ...
output:
49657566 56023919 387074343 97051536 701572244 211048577 711758412 308100110 761007271 711758412 178698065 285212675 80216065 43380497 267677376 818005792 53239701 765628773 970145625 387074343 436731906 422725927 479157293 977872021 436731906 925779210 487662742 705549251 267677376 711758412 526851...
result:
ok 10000 lines
Test #5:
score: 0
Accepted
time: 138ms
memory: 21008kb
input:
10000 8 7 6 8 6 5 7 4 6 1 4 2 5 3 5 10 10 7 8 7 9 8 2 8 6 7 1 7 5 9 4 1 3 6 10 2 6 3 6 5 6 7 2 1 3 4 5 8 5 9 5 10 4 10 6 5 2 5 4 6 8 5 10 5 9 5 1 8 3 6 7 1 8 5 2 3 5 6 5 1 2 8 2 4 1 7 5 9 5 1 3 1 7 5 9 7 6 3 8 6 2 1 4 9 9 9 8 4 8 3 8 6 9 2 8 7 6 1 2 5 6 9 2 5 8 5 7 8 9 7 1 8 4 8 6 9 3 1 8 6 7 8 6 2 ...
output:
711758412 286902823 691130166 841483019 650641410 887328317 331207619 733278261 56023919 977872021 414394648 183319566 239374924 696059768 855285904 761007271 711758412 86268032 599710576 728310932 178698065 178698065 422725927 219002589 178698065 202450068 599710576 56023919 449579681 760637552 925...
result:
ok 10000 lines
Test #6:
score: 0
Accepted
time: 142ms
memory: 21860kb
input:
10000 9 8 1 2 8 4 1 3 2 7 1 6 7 9 3 5 1 9 7 5 1 7 3 7 9 5 2 3 8 1 6 8 4 6 9 7 8 4 7 5 4 3 4 6 8 1 3 9 8 2 7 9 8 7 2 8 9 8 5 8 1 2 3 7 6 3 4 7 8 6 8 4 6 2 4 5 8 7 5 1 6 3 7 9 9 8 7 8 2 9 5 9 1 5 3 1 6 2 4 8 10 2 10 4 10 6 4 1 10 9 6 8 9 5 10 7 4 3 2 10 3 9 5 3 4 3 7 9 6 3 10 6 2 9 8 5 1 2 10 8 5 2 8 ...
output:
211048577 354315128 178698065 705549251 285212675 138645051 449579681 286902823 925779210 294297225 519087065 368179632 422725927 603876215 539175192 867301808 977540027 669439919 211048577 701572244 977872021 138645051 267677376 855285904 977872021 286902823 925286249 705549251 219002589 331207619 ...
result:
ok 10000 lines
Test #7:
score: 0
Accepted
time: 136ms
memory: 19456kb
input:
10000 8 4 2 6 2 1 6 5 1 3 1 7 5 8 5 8 4 3 8 4 6 8 2 3 5 8 1 4 7 5 9 6 1 8 6 7 8 5 6 4 1 9 6 3 1 2 5 8 3 2 5 2 7 2 8 2 1 7 4 3 6 8 10 10 2 7 10 3 7 8 7 5 10 1 5 4 3 6 4 9 7 8 5 4 8 4 2 5 7 4 6 8 1 7 3 1 9 3 1 8 1 5 1 6 5 2 6 9 5 7 5 4 2 10 1 3 6 1 2 3 7 3 8 7 9 1 10 7 5 7 4 10 10 3 2 10 3 5 10 9 3 1 ...
output:
422725927 977872021 867301808 407446676 466833287 387074343 97051536 292325385 301691628 765628773 285212675 711758412 650641410 178698065 543242114 286902823 473241769 109930120 841975980 836553418 422725927 286902823 414394648 739440264 436731906 56023919 436731906 530918109 603876215 977872021 40...
result:
ok 10000 lines
Test #8:
score: 0
Accepted
time: 151ms
memory: 21608kb
input:
10000 9 9 3 7 9 2 3 5 2 6 2 1 9 4 5 8 9 10 4 6 9 4 8 6 5 4 10 5 7 8 2 8 3 7 1 2 10 5 4 1 4 3 4 9 3 6 3 7 9 8 7 2 4 10 7 10 3 8 4 3 10 8 6 10 9 4 5 6 2 8 1 2 7 5 10 10 9 4 9 6 10 5 10 2 6 1 10 3 1 8 3 7 10 10 9 7 10 7 2 7 3 10 1 3 4 3 8 9 6 3 5 6 9 2 4 7 4 5 7 9 5 3 5 6 7 8 7 1 2 9 2 4 1 4 9 2 7 2 8 ...
output:
409773147 306621231 836553418 760637552 519087065 304649390 97051536 742521264 387074343 855285904 874737082 358875008 733278261 698524570 908525604 387074343 970145625 449579681 286902823 239374924 650641410 691130166 765628773 603876215 839572800 977872021 742521264 908032643 874737082 299719788 7...
result:
ok 10000 lines
Test #9:
score: 0
Accepted
time: 145ms
memory: 21000kb
input:
10000 9 8 4 5 4 6 4 3 5 7 4 9 6 1 9 2 9 10 3 9 10 3 2 10 6 2 1 6 8 2 4 1 5 3 7 9 9 9 3 7 9 4 3 5 3 2 3 6 5 1 6 8 9 8 6 1 8 1 5 6 7 6 4 8 3 6 2 7 8 2 3 7 2 8 2 6 8 5 2 1 3 4 2 10 2 7 8 7 9 2 5 8 10 8 3 7 1 7 4 8 6 7 9 3 8 4 3 5 3 2 8 9 2 1 5 6 8 7 4 9 5 1 6 5 4 6 9 6 3 4 2 9 8 1 7 4 8 2 4 8 4 3 2 5 3...
output:
331207619 28098733 97051536 599710576 701572244 277043619 368179632 138645051 711758412 626059423 86268032 414394648 368179632 993314752 321410036 530918109 711758412 712327454 603876215 49657566 705549251 765628773 56023919 299719788 887328316 839572800 650641410 211048577 286902823 908032643 28690...
result:
ok 10000 lines
Test #10:
score: 0
Accepted
time: 149ms
memory: 19640kb
input:
10000 10 4 9 7 4 2 4 5 4 6 7 10 2 3 9 8 10 1 8 8 2 4 3 2 5 2 6 4 1 4 8 3 7 1 8 8 7 6 7 4 8 5 4 1 6 2 5 3 4 8 7 2 3 2 5 3 1 5 8 1 4 7 6 2 9 5 9 6 9 4 6 7 9 8 4 3 6 1 6 2 5 10 7 1 4 7 2 7 5 2 8 5 3 2 6 7 10 4 9 2 8 6 2 3 6 7 2 8 3 5 6 4 5 1 2 10 2 8 5 8 10 8 4 10 7 8 3 2 1 10 6 4 9 10 10 3 5 6 5 10 5 ...
output:
440213438 977872021 285212675 285212675 705549251 267677376 436731906 267677376 440213438 712327454 711758412 191268549 321410036 436731906 839572800 49657566 519087065 178698065 977872021 285212675 574298605 368179632 466833287 696059768 86268033 308100110 487662742 887328317 977872021 701572244 99...
result:
ok 10000 lines
Test #11:
score: 0
Accepted
time: 148ms
memory: 19012kb
input:
10000 8 1 3 8 3 2 3 6 8 5 8 4 1 7 1 10 5 7 10 7 2 5 4 5 8 10 6 7 1 5 3 2 9 8 9 4 7 2 4 1 4 5 4 9 1 3 2 6 4 8 9 8 5 7 3 5 2 5 6 5 4 7 8 3 1 7 9 1 5 9 5 3 1 7 3 8 3 6 3 4 1 2 8 8 1 2 4 2 6 2 7 2 8 7 3 8 5 6 9 4 5 3 4 6 4 7 3 1 5 9 3 2 1 8 7 9 1 6 3 1 2 3 5 2 4 3 8 5 9 5 7 1 8 5 3 7 3 4 3 8 7 1 3 6 1 2...
output:
202450068 449579681 742521264 56023919 705549251 599710576 765628773 887328316 599710576 97051536 286902823 603876215 321410036 221832080 294297225 479157293 650641410 765628773 908525604 285212675 125704848 414394648 599254713 286902823 707938599 13864507 599710576 304649390 691130166 56023919 7656...
result:
ok 10000 lines
Test #12:
score: 0
Accepted
time: 0ms
memory: 2156kb
input:
1 2 1 2
output:
1
result:
ok single line: '1'
Extra Test:
score: 0
Extra Test Passed