Skip to main content

competitive/tools/
main.rs

1#[codesnip::skip]
2use crate::tools::{ScanSource, Scanner, read_stdin_all_unchecked};
3
4#[cfg_attr(nightly, rust_minify::skip)]
5pub fn solve() {
6    crate::prepare!();
7    sc!(_n);
8}
9
10crate::main!("library: https://github.com/to-omer/competitive-library, bundled with codesnip");
11
12#[allow(unused_imports)]
13use std::{
14    cmp::{Ordering, Reverse},
15    collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque},
16};
17
18mod main_macros {
19    /// Prepare useful macros.
20    /// - `prepare!();`: default (all input scanner (`sc!`, `sv!`) + buf print (`pp!`, `dg!`))
21    /// - `prepare!(fast);`: fast stdin/stdout for valid input (`sc!`, `sv!`, `pp!`, `dg!`)
22    /// - `prepare!(?);`: interactive (line scanner (`scln!`) + buf print (`pp!`, `dg!`))
23    #[macro_export]
24    #[allow(clippy::crate_in_macro_def)]
25    macro_rules! prepare {
26        (@output ($dol:tt)) => {
27            #[allow(unused_imports)]
28            use std::io::Write as _;
29            let __out = std::io::stdout();
30            #[allow(unused_mut,unused_variables)]
31            let mut __out = std::io::BufWriter::new(__out.lock());
32            #[allow(unused_macros)]
33            /// [`iter_print!`] for buffered stdout.
34            macro_rules! pp { ($dol($dol t:tt)*) => { $dol crate::iter_print!(__out, $dol($dol t)*) } }
35            $crate::prepare!(@debug ($));
36        };
37        (@debug ($dol:tt)) => {
38            #[cfg(debug_assertions)]
39            #[allow(unused_macros)]
40            /// [`iter_print!`] for buffered stderr. Do nothing in release mode.
41            macro_rules! dg {
42                ($dol($dol t:tt)*) => {{
43                    #[allow(unused_imports)]
44                    use std::io::Write as _;
45                    let __err = std::io::stderr();
46                    #[allow(unused_mut,unused_variables)]
47                    let mut __err = std::io::BufWriter::new(__err.lock());
48                    $dol crate::iter_print!(__err, $dol($dol t)*);
49                    let _ = __err.flush();
50                }}
51            }
52            #[cfg(not(debug_assertions))]
53            #[allow(unused_macros)]
54            /// [`iter_print!`] for buffered stderr. Do nothing in release mode.
55            macro_rules! dg { ($dol($dol t:tt)*) => {} }
56        };
57        (@normal ($dol:tt)) => {
58            let __in_buf = read_stdin_all_unchecked();
59            #[allow(unused_mut,unused_variables)]
60            let mut __scanner = Scanner::new(&__in_buf);
61            #[allow(unused_macros)]
62            macro_rules! sc { ($dol($dol t:tt)*) => { $dol crate::scan!(__scanner, $dol($dol t)*) } }
63            #[allow(unused_macros)]
64            macro_rules! sv { ($dol($dol t:tt)*) => { $dol crate::scan_value!(__scanner, $dol($dol t)*) } }
65        };
66        (@interactive ($dol:tt)) => {
67            #[allow(unused_macros)]
68            /// Scan a line, and previous line will be truncated in the next call.
69            macro_rules! scln {
70                ($dol($dol t:tt)*) => {
71                    let __in_buf = read_stdin_line();
72                    #[allow(unused_mut,unused_variables)]
73                    let mut __scanner = Scanner::new(&__in_buf);
74                    $dol crate::scan!(__scanner, $dol($dol t)*)
75                }
76            }
77            #[allow(unused_macros)]
78            /// Scan a line, and previous line will be truncated in the next call.
79            macro_rules! svln {
80                ($dol($dol t:tt)*) => {{
81                    let __in_buf = read_stdin_line();
82                    #[allow(unused_mut,unused_variables)]
83                    let mut __scanner = Scanner::new(&__in_buf);
84                    $dol crate::scan_value!(__scanner, $dol($dol t)*)
85                }}
86            }
87        };
88        (@fast ($dol:tt)) => {
89            #[allow(unused_mut, unused_variables)]
90            let mut __scanner = unsafe { FastInput::stdin() };
91            #[allow(unused_mut, unused_variables)]
92            let mut __out = FastOutput::new(std::io::stdout().lock());
93            #[allow(unused_macros)]
94            macro_rules! sc { ($dol($dol t:tt)*) => { $dol crate::scan!(__scanner, $dol($dol t)*) } }
95            #[allow(unused_macros)]
96            macro_rules! sv { ($dol($dol t:tt)*) => { $dol crate::scan_value!(__scanner, $dol($dol t)*) } }
97            #[allow(unused_macros)]
98            macro_rules! pp { ($dol($dol t:tt)*) => { $dol crate::iter_print!(fast; __out, $dol($dol t)*) } }
99            $crate::prepare!(@debug ($));
100        };
101        (fast) => {
102            $crate::prepare!(@fast ($));
103        };
104        () => { $crate::prepare!(@output ($)); $crate::prepare!(@normal ($)) };
105        (?) => { $crate::prepare!(@output ($)); $crate::prepare!(@interactive ($)) };
106    }
107    #[macro_export]
108    macro_rules! main {
109        (avx2; $($t:tt)*) => {
110            #[allow(dead_code)]
111            fn main() {
112                #[target_feature(enable = "avx2")]
113                unsafe fn solve_avx2() {
114                    solve();
115                }
116                unsafe { solve_avx2() }
117            }
118        };
119        (large_stack; $($t:tt)*) => {
120            #[allow(dead_code)]
121            fn main() {
122                const STACK_SIZE: usize = 512 * 1024 * 1024;
123                ::std::thread::Builder::new()
124                    .stack_size(STACK_SIZE)
125                    .spawn(solve)
126                    .unwrap()
127                    .join()
128                    .unwrap();
129            }
130        };
131        ($($t:tt)*) => {
132            #[allow(dead_code)]
133            fn main() {
134                solve();
135            }
136        };
137    }
138}