QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#552592 | #9242. An Easy Geometry Problem | ucup-team296# | AC ✓ | 3098ms | 12816kb | Rust | 39.3kb | 2024-09-07 23:54:49 | 2024-09-07 23:54:51 |
Judging History
answer
//
pub mod solution {
//{"name":"a","group":"Manual","url":"","interactive":false,"timeLimit":2000,"tests":[{"input":"","output":""}],"testType":"single","input":{"type":"stdin","fileName":null,"pattern":null},"output":{"type":"stdout","fileName":null,"pattern":null},"languages":{"java":{"taskClass":"a"}}}
use std::vec;
#[allow(unused)]
use crate::dbg;
use crate::algo_lib::io::input::Input;
use crate::algo_lib::io::output::Output;
use crate::algo_lib::math::modulo::Mod9;
use crate::algo_lib::misc::binary_search::binary_search_last_true;
use crate::algo_lib::seg_trees::lazy_seg_tree::SegTree;
use crate::algo_lib::seg_trees::seg_tree_trait::SegTreeNode;
type Mod = Mod9;
pub struct Context {
powers: Vec<Mod>,
#[allow(unused)]
multiplier: Mod,
}
impl Context {
pub fn new(max_len: usize, multiplier: Mod) -> Self {
let mut powers = Vec::with_capacity(max_len + 1);
powers.push(Mod::ONE);
for i in 1..=max_len {
powers.push(powers[i - 1] * multiplier);
}
Self { powers, multiplier }
}
}
#[derive(Copy, Clone, Default)]
pub struct Node {
hash: Mod,
hash_rev: Mod,
size: usize,
}
impl Node {
pub fn new(hash: Mod) -> Self {
Self {
hash,
hash_rev: hash,
size: 1,
}
}
}
impl SegTreeNode for Node {
fn join_nodes(lhs: &Self, rhs: &Self, ctx: &Self::Context) -> Self {
Self {
hash: lhs.hash * ctx.powers[rhs.size] + rhs.hash,
hash_rev: rhs.hash_rev * ctx.powers[lhs.size] + lhs.hash_rev,
size: lhs.size + rhs.size,
}
}
fn apply_update(node: &mut Self, update: &Self::Update) {
todo!()
}
fn join_updates(current: &mut Self::Update, add: &Self::Update) {
todo!()
}
type Update = ();
type Context = Context;
}
fn solve(input: &mut Input, out: &mut Output, _test_case: usize) {
let n = input.usize();
let q = input.usize();
let k = Mod::new(input.i32());
let b = Mod::new(input.i32());
let a = input.vec::<i32>(n);
let mut am = vec![Mod::ZERO; n];
for i in 0..n {
am[i] = Mod::new(a[i]);
}
let mut deltas = vec![Mod::ZERO; n - 1];
for i in 0..n - 1 {
deltas[i] = Mod::new(a[i + 1] - a[i]);
}
let multiplier = Mod::new(2390171);
let context = Context::new(n + 1, multiplier);
let mut deltas_seg_tree = SegTree::new_with_context(
n,
|i| {
if i == n - 1 {
Node::new(Mod::ZERO)
} else {
Node::new(deltas[i])
}
},
context,
);
let mut expected_hashes = vec![Mod::ZERO; n + 1];
for len in 1..=n {
expected_hashes[len] = expected_hashes[len - 1] * multiplier + k;
}
for _ in 0..q {
let q_type = input.usize();
if q_type == 1 {
let l = input.usize() - 1;
let r = input.usize() - 1;
let v = Mod::new(input.i32());
// for i in l..=r {
// am[i] += v;
// }
if l != 0 {
deltas[l - 1] += v;
deltas_seg_tree.update_point(l - 1, Node::new(deltas[l - 1]));
}
if r != n - 1 {
deltas[r] -= v;
deltas_seg_tree.update_point(r, Node::new(deltas[r]));
}
} else {
assert_eq!(q_type, 2);
let mid = input.usize() - 1;
// let mut r = 0;
// while mid - r > 0 && mid + r + 1 < n {
// r += 1;
// let my = am[mid + r] - am[mid - r];
// let expected = k * Mod::new(r) + b;
// if my != expected {
// r -= 1;
// break;
// }
// }
let res = {
if mid == 0 || mid == n - 1 {
0
} else {
let expected = k + b;
let real = deltas[mid - 1] + deltas[mid];
if expected != real {
0
} else {
// dbg!(n, mid);
binary_search_last_true(1..(mid + 1).min(n - mid), |check| {
let len = check - 1;
// dbg!(n, mid, len);
let to1 = mid - 1;
let from1 = to1 - len;
let from2 = mid + 1;
let to2 = from2 + len;
// dbg!("Checking", mid, len, from1, to1, from2, to2);
assert!(to2 < n);
let hash = deltas_seg_tree.get(from1..from1 + len).hash
+ deltas_seg_tree.get(from2..from2 + len).hash_rev;
let expected_hash = expected_hashes[len];
hash == expected_hash
// if check == 2 {
// dbg!(deltas, mid, k);
// }
// for i in 0..len {
// let ss = deltas[from1 + i] + deltas[to2 - 1 - i];
// dbg!(i, deltas[from1 + i], deltas[to2 - 1 - i], ss, k);
// if ss != k {
// return false;
// }
// }
// true
})
.unwrap()
// let mut r = 1;
// loop {
// if mid - r == 0 || mid + r == n - 1 {
// break;
// }
// let sum_deltas = deltas[mid - r - 1] + deltas[mid + r];
// if sum_deltas != k {
// break;
// } else {
// r += 1;
// }
// }
// r
}
}
};
// assert_eq!(res, r);
out.println(res);
}
}
}
pub(crate) fn run(mut input: Input, mut output: Output) -> bool {
solve(&mut input, &mut output, 1);
output.flush();
true
}
}
pub mod algo_lib {
pub mod collections {
pub mod last_exn {
use std::collections::BTreeSet;
pub trait LastExn<T> {
fn last_exn(&self) -> &T;
}
impl<T> LastExn<T> for &[T] {
fn last_exn(&self) -> &T {
self.last().unwrap()
}
}
impl<T> LastExn<T> for Vec<T> {
fn last_exn(&self) -> &T {
self.last().unwrap()
}
}
impl<T> LastExn<T> for BTreeSet<T> {
fn last_exn(&self) -> &T {
self.iter().next_back().unwrap()
}
}
}
}
pub mod io {
pub mod input {
use std::fmt::Debug;
use std::io::Read;
use std::marker::PhantomData;
use std::path::Path;
use std::str::FromStr;
pub struct Input {
input: Box<dyn Read>,
buf: Vec<u8>,
at: usize,
buf_read: usize,
}
macro_rules! read_integer_fun {
($t:ident) => {
#[allow(unused)]
pub fn $t(&mut self) -> $t {
self.read_integer()
}
};
}
impl Input {
const DEFAULT_BUF_SIZE: usize = 4096;
///
/// Using with stdin:
/// ```no_run
/// use algo_lib::io::input::Input;
/// let stdin = std::io::stdin();
/// let input = Input::new(Box::new(stdin));
/// ```
///
/// For read files use ``new_file`` instead.
///
///
pub fn new(input: Box<dyn Read>) -> Self {
Self {
input,
buf: vec![0; Self::DEFAULT_BUF_SIZE],
at: 0,
buf_read: 0,
}
}
pub fn new_stdin() -> Self {
let stdin = std::io::stdin();
Self::new(Box::new(stdin))
}
pub fn new_file<P: AsRef<Path>>(path: P) -> Self {
let file = std::fs::File::open(&path)
.unwrap_or_else(|_| panic!("Can't open file: {:?}", path.as_ref().as_os_str()));
Self::new(Box::new(file))
}
pub fn new_with_size(input: Box<dyn Read>, buf_size: usize) -> Self {
Self {
input,
buf: vec![0; buf_size],
at: 0,
buf_read: 0,
}
}
pub fn new_file_with_size<P: AsRef<Path>>(path: P, buf_size: usize) -> Self {
let file = std::fs::File::open(&path)
.unwrap_or_else(|_| panic!("Can't open file: {:?}", path.as_ref().as_os_str()));
Self::new_with_size(Box::new(file), buf_size)
}
pub fn get(&mut self) -> Option<u8> {
if self.refill_buffer() {
let res = self.buf[self.at];
self.at += 1;
Some(res)
} else {
None
}
}
pub fn peek(&mut self) -> Option<u8> {
if self.refill_buffer() {
Some(self.buf[self.at])
} else {
None
}
}
pub fn skip_whitespace(&mut self) {
while let Some(b) = self.peek() {
if !char::from(b).is_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 char::from(c).is_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()
}
pub fn has_more_elements(&mut self) -> bool {
!self.is_exhausted()
}
pub fn read<T: Readable>(&mut self) -> T {
T::read(self)
}
pub fn vec<T: Readable>(&mut self, size: usize) -> Vec<T> {
let mut res = Vec::with_capacity(size);
for _ in 0usize..size {
res.push(self.read());
}
res
}
pub fn string_vec(&mut self, size: usize) -> Vec<Vec<u8>> {
let mut res = Vec::with_capacity(size);
for _ in 0usize..size {
res.push(self.string());
}
res
}
pub fn read_line(&mut self) -> String {
let mut res = String::new();
while let Some(c) = self.get() {
if c == b'\n' {
break;
}
if c == b'\r' {
if self.peek() == Some(b'\n') {
self.get();
}
break;
}
res.push(c.into());
}
res
}
#[allow(clippy::should_implement_trait)]
pub fn into_iter<T: Readable>(self) -> InputIterator<T> {
InputIterator {
input: self,
phantom: Default::default(),
}
}
fn read_integer<T: FromStr + Debug>(&mut self) -> T
where
<T as FromStr>::Err: Debug,
{
let res = self.read_string();
res.parse::<T>().unwrap()
}
fn read_string(&mut self) -> String {
match self.next_token() {
None => {
panic!("Input exhausted");
}
Some(res) => unsafe { String::from_utf8_unchecked(res) },
}
}
pub fn string_as_string(&mut self) -> String {
self.read_string()
}
pub fn string(&mut self) -> Vec<u8> {
self.read_string().into_bytes()
}
fn read_char(&mut self) -> char {
self.skip_whitespace();
self.get().unwrap().into()
}
fn read_float(&mut self) -> f64 {
self.read_string().parse().unwrap()
}
pub fn f64(&mut self) -> f64 {
self.read_float()
}
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
}
}
read_integer_fun!(i32);
read_integer_fun!(i64);
read_integer_fun!(i128);
read_integer_fun!(u32);
read_integer_fun!(u64);
read_integer_fun!(usize);
}
pub trait Readable {
fn read(input: &mut Input) -> Self;
}
impl Readable for String {
fn read(input: &mut Input) -> Self {
input.read_string()
}
}
impl Readable for char {
fn read(input: &mut Input) -> Self {
input.read_char()
}
}
impl Readable for f64 {
fn read(input: &mut Input) -> Self {
input.read_string().parse().unwrap()
}
}
impl Readable for f32 {
fn read(input: &mut Input) -> Self {
input.read_string().parse().unwrap()
}
}
impl<T: Readable> Readable for Vec<T> {
fn read(input: &mut Input) -> Self {
let size = input.read();
input.vec(size)
}
}
pub struct InputIterator<T: Readable> {
input: Input,
phantom: PhantomData<T>,
}
impl<T: Readable> Iterator for InputIterator<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.input.skip_whitespace();
self.input.peek().map(|_| self.input.read())
}
}
macro_rules! read_integer {
($t:ident) => {
impl Readable for $t {
fn read(input: &mut Input) -> Self {
input.read_integer()
}
}
};
}
read_integer!(i8);
read_integer!(i16);
read_integer!(i32);
read_integer!(i64);
read_integer!(i128);
read_integer!(isize);
read_integer!(u8);
read_integer!(u16);
read_integer!(u32);
read_integer!(u64);
read_integer!(u128);
read_integer!(usize);
}
pub mod output {
use std::io::Write;
pub struct Output {
output: Box<dyn Write>,
buf: Vec<u8>,
at: usize,
auto_flush: bool,
}
impl Output {
const DEFAULT_BUF_SIZE: usize = 4096;
pub fn new(output: Box<dyn Write>) -> Self {
Self {
output,
buf: vec![0; Self::DEFAULT_BUF_SIZE],
at: 0,
auto_flush: false,
}
}
pub fn new_stdout() -> Self {
let stdout = std::io::stdout();
Self::new(Box::new(stdout))
}
pub fn new_file(path: impl AsRef<std::path::Path>) -> Self {
let file = std::fs::File::create(path).unwrap();
Self::new(Box::new(file))
}
pub fn new_with_auto_flush(output: Box<dyn Write>) -> Self {
Self {
output,
buf: vec![0; Self::DEFAULT_BUF_SIZE],
at: 0,
auto_flush: true,
}
}
pub fn flush(&mut self) {
if self.at != 0 {
self.output.write_all(&self.buf[..self.at]).unwrap();
self.at = 0;
self.output.flush().expect("Couldn't flush output");
}
}
pub fn print<T: Writable>(&mut self, s: T) {
s.write(self);
}
pub fn println<T: Writable>(&mut self, s: T) {
s.write(self);
self.put(b'\n');
}
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]) {
for i in arg {
i.write(self);
self.put(b'\n');
}
}
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_iter_ref<'a, T: 'a + Writable, I: Iterator<Item = &'a T>>(&mut self, iter: I) {
let mut first = true;
for e in iter {
if first {
first = false;
} else {
self.put(b' ');
}
e.write(self);
}
}
}
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;
}
if self.auto_flush {
self.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<T: Writable> Writable for [T] {
fn write(&self, output: &mut Output) {
output.print_iter_ref(self.iter());
}
}
impl<T: Writable> Writable for Vec<T> {
fn write(&self, output: &mut Output) {
self[..].write(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!(u8);
write_to_string!(u16);
write_to_string!(u32);
write_to_string!(u64);
write_to_string!(u128);
write_to_string!(usize);
write_to_string!(i8);
write_to_string!(i16);
write_to_string!(i32);
write_to_string!(i64);
write_to_string!(i128);
write_to_string!(isize);
write_to_string!(f32);
write_to_string!(f64);
impl<T: Writable, U: Writable> Writable for (T, U) {
fn write(&self, output: &mut Output) {
self.0.write(output);
output.put(b' ');
self.1.write(output);
}
}
impl<T: Writable, U: Writable, V: Writable> Writable for (T, U, V) {
fn write(&self, output: &mut Output) {
self.0.write(output);
output.put(b' ');
self.1.write(output);
output.put(b' ');
self.2.write(output);
}
}
}
}
pub mod math {
pub mod modulo {
use crate::algo_lib::collections::last_exn::LastExn;
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::num_traits::ConvSimple;
use crate::algo_lib::misc::num_traits::HasConstants;
use crate::algo_lib::misc::num_traits::Number;
use std::io::Write;
use std::marker::PhantomData;
pub trait Value: Clone + Copy + Eq + Default + Ord {
fn val() -> i32;
}
#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
pub struct ModWithValue<M>(i32, PhantomData<M>)
where
M: Value;
impl<M> ModWithValue<M>
where
M: Value,
{
#[allow(unused)]
pub const ZERO: Self = Self(0, PhantomData);
#[allow(unused)]
pub const ONE: Self = Self(1, PhantomData);
#[allow(unused)]
pub const TWO: Self = Self(2, PhantomData);
fn rev_rec(a: i32, m: i32) -> i32 {
if a == 1 {
return a;
}
((1 - Self::rev_rec(m % a, a) as i64 * m as i64) / a as i64 + m as i64) as i32
}
#[allow(dead_code)]
pub fn inv(self) -> Self {
ModWithValue(Self::rev_rec(self.0, M::val()), PhantomData)
}
pub fn value(&self) -> i32 {
self.0
}
pub fn i64(&self) -> i64 {
self.0 as i64
}
#[allow(dead_code)]
pub fn new<T: Number>(x: T) -> Self {
let mut x = x.to_i32();
if x < 0 {
x += M::val();
if x < 0 {
x %= M::val();
x += M::val();
}
} else if x >= M::val() {
x -= M::val();
if x >= M::val() {
x %= M::val();
}
}
assert!(0 <= x && x < M::val());
Self(x, PhantomData)
}
pub fn pown(self, pw: usize) -> Self {
if pw == 0 {
Self::ONE
} else if pw == 1 {
self
} else {
let half = self.pown(pw / 2);
let res = half * half;
if pw % 2 == 0 {
res
} else {
res * self
}
}
}
pub fn gen_powers(base: Self, n: usize) -> Vec<Self> {
let mut res = Vec::with_capacity(n);
res.push(Self::ONE);
for _ in 1..n {
res.push(*res.last_exn() * base);
}
res
}
}
impl<M> std::fmt::Display for ModWithValue<M>
where
M: Value,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<M> std::fmt::Debug for ModWithValue<M>
where
M: Value + Copy + Eq,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
const MAX: i32 = 100;
if self.0 <= MAX {
write!(f, "{}", self.0)
} else if self.0 >= M::val() - MAX {
write!(f, "-{}", M::val() - self.0)
} else {
for denom in 1..MAX {
let num = *self * Self(denom, PhantomData);
if num.0 <= MAX {
return write!(f, "{}/{}", num.0, denom);
} else if num.0 >= M::val() - MAX {
return write!(f, "-{}/{}", M::val() - num.0, denom);
}
}
write!(f, "(?? {} ??)", self.0)
}
}
}
impl<M> std::ops::Add for ModWithValue<M>
where
M: Value,
{
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
let res = self.0 + rhs.0;
if res >= M::val() {
ModWithValue(res - M::val(), PhantomData)
} else {
ModWithValue(res, PhantomData)
}
}
}
impl<M> std::ops::AddAssign for ModWithValue<M>
where
M: Value,
{
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
if self.0 >= M::val() {
self.0 -= M::val();
}
}
}
impl<M> std::ops::Sub for ModWithValue<M>
where
M: Value,
{
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
let res = self.0 - rhs.0;
if res < 0 {
ModWithValue(res + M::val(), PhantomData)
} else {
ModWithValue(res, PhantomData)
}
}
}
impl<M> std::ops::SubAssign for ModWithValue<M>
where
M: Value,
{
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
if self.0 < 0 {
self.0 += M::val();
}
}
}
impl<M> std::ops::Mul for ModWithValue<M>
where
M: Value,
{
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
let res = (self.0 as i64) * (rhs.0 as i64) % (M::val() as i64);
ModWithValue(res as i32, PhantomData)
}
}
impl<M> std::ops::MulAssign for ModWithValue<M>
where
M: Value,
{
fn mul_assign(&mut self, rhs: Self) {
self.0 = ((self.0 as i64) * (rhs.0 as i64) % (M::val() as i64)) as i32;
}
}
impl<M> std::ops::Div for ModWithValue<M>
where
M: Value,
{
type Output = Self;
#[allow(clippy::suspicious_arithmetic_impl)]
fn div(self, rhs: Self) -> Self::Output {
let rhs_inv = rhs.inv();
self * rhs_inv
}
}
impl<M> std::ops::DivAssign for ModWithValue<M>
where
M: Value,
{
#[allow(clippy::suspicious_op_assign_impl)]
fn div_assign(&mut self, rhs: Self) {
*self *= rhs.inv();
}
}
impl<M> Writable for ModWithValue<M>
where
M: Value,
{
fn write(&self, output: &mut Output) {
output.write_fmt(format_args!("{}", self.0)).unwrap();
}
}
impl<M> Readable for ModWithValue<M>
where
M: Value,
{
fn read(input: &mut Input) -> Self {
let i32 = input.i32();
Self::new(i32)
}
}
impl<M> HasConstants<ModWithValue<M>> for ModWithValue<M>
where
M: Value,
{
// This doesn't make much sense, but hope we never use
const MAX: ModWithValue<M> = ModWithValue::ZERO;
const MIN: ModWithValue<M> = ModWithValue::ZERO;
const ZERO: ModWithValue<M> = ModWithValue::ZERO;
const ONE: ModWithValue<M> = ModWithValue::ONE;
const TWO: ModWithValue<M> = ModWithValue::TWO;
}
impl<M> ConvSimple<ModWithValue<M>> for ModWithValue<M>
where
M: Value,
{
fn from_i32(val: i32) -> ModWithValue<M> {
ModWithValue::new(val)
}
fn to_i32(self) -> i32 {
self.0
}
fn to_f64(self) -> f64 {
self.0 as f64
}
}
pub trait ConstValue: Value + Copy {
const VAL: i32;
}
impl<V: ConstValue> Value for V {
fn val() -> i32 {
Self::VAL
}
}
#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
pub struct Value7();
impl ConstValue for Value7 {
const VAL: i32 = 1_000_000_007;
}
pub type Mod7 = ModWithValue<Value7>;
#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
pub struct Value9();
impl ConstValue for Value9 {
const VAL: i32 = 1_000_000_009;
}
pub type Mod9 = ModWithValue<Value9>;
#[derive(Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Hash)]
#[allow(non_camel_case_types)]
pub struct Value_998_244_353();
impl ConstValue for Value_998_244_353 {
const VAL: i32 = 998_244_353;
}
#[allow(non_camel_case_types)]
pub type Mod_998_244_353 = ModWithValue<Value_998_244_353>;
pub trait ModuloTrait: Number {
fn mod_value() -> i32;
fn pown(self, n: usize) -> Self;
}
impl<V: Value> ModuloTrait for ModWithValue<V> {
fn mod_value() -> i32 {
V::val()
}
fn pown(self, n: usize) -> Self {
self.pown(n)
}
}
}
}
pub mod misc {
pub mod binary_search {
use crate::algo_lib::misc::num_traits::Number;
use std::ops::Range;
pub fn binary_search_first_true<T>(range: Range<T>, mut f: impl FnMut(T) -> bool) -> T
where
T: Number,
{
// we can't store [range.start - 1] into [left], because it could overflow
let mut left_plus_one = range.start;
let mut right = range.end;
while right > left_plus_one {
let mid = left_plus_one + (right - left_plus_one) / T::TWO;
if f(mid) {
right = mid;
} else {
left_plus_one = mid + T::ONE;
}
}
right
}
pub fn binary_search_last_true<T>(range: Range<T>, mut f: impl FnMut(T) -> bool) -> Option<T>
where
T: Number,
{
let first_false = binary_search_first_true(range.clone(), |x| !f(x));
if first_false == range.start {
None
} else {
Some(first_false - T::ONE)
}
}
#[test]
fn simple_stress() {
const N: usize = 50;
for n in 1..N {
for cnt_false in 0..=n {
let mut a = vec![false; cnt_false];
a.resize(n, true);
let mut max_f_calls = ((n + 1) as f64).log2().ceil() as i32;
let f_is_true = |id: usize| -> bool {
max_f_calls -= 1;
assert!(max_f_calls >= 0);
a[id]
};
let result = binary_search_first_true(0..n, f_is_true);
assert_eq!(result, cnt_false);
}
}
}
}
pub mod dbg_macro {
#[macro_export]
#[allow(unused_macros)]
macro_rules! dbg {
($first_val:expr, $($val:expr),+ $(,)?) => {
eprint!("[{}:{}] {} = {:?}",
file!(), line!(), stringify!($first_val), &$first_val);
($(eprint!(", {} = {:?}", stringify!($val), &$val)),+,);
eprintln!();
};
($first_val:expr) => {
eprintln!("[{}:{}] {} = {:?}",
file!(), line!(), stringify!($first_val), &$first_val)
};
}
}
pub mod num_traits {
use std::cmp::Ordering;
use std::fmt::Debug;
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::Sub;
use std::ops::SubAssign;
pub trait HasConstants<T> {
const MAX: T;
const MIN: T;
const ZERO: T;
const ONE: T;
const TWO: T;
}
pub trait ConvSimple<T> {
fn from_i32(val: i32) -> T;
fn to_i32(self) -> i32;
fn to_f64(self) -> f64;
}
pub trait Signum {
fn signum(&self) -> i32;
}
pub trait Number:
Copy
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
+ PartialOrd
+ PartialEq
+ HasConstants<Self>
+ Default
+ Debug
+ Sized
+ ConvSimple<Self>
{
}
impl<
T: Copy
+ Add<Output = Self>
+ AddAssign
+ Sub<Output = Self>
+ SubAssign
+ Mul<Output = Self>
+ MulAssign
+ Div<Output = Self>
+ DivAssign
+ PartialOrd
+ PartialEq
+ HasConstants<Self>
+ Default
+ Debug
+ Sized
+ ConvSimple<Self>,
> Number for T
{
}
macro_rules! has_constants_impl {
($t: ident) => {
impl HasConstants<$t> for $t {
// TODO: remove `std` for new rust version..
const MAX: $t = std::$t::MAX;
const MIN: $t = std::$t::MIN;
const ZERO: $t = 0;
const ONE: $t = 1;
const TWO: $t = 2;
}
impl ConvSimple<$t> for $t {
fn from_i32(val: i32) -> $t {
val as $t
}
fn to_i32(self) -> i32 {
self as i32
}
fn to_f64(self) -> f64 {
self as f64
}
}
};
}
has_constants_impl!(i32);
has_constants_impl!(i64);
has_constants_impl!(i128);
has_constants_impl!(u32);
has_constants_impl!(u64);
has_constants_impl!(u128);
has_constants_impl!(usize);
has_constants_impl!(u8);
impl ConvSimple<Self> for f64 {
fn from_i32(val: i32) -> Self {
val as f64
}
fn to_i32(self) -> i32 {
self as i32
}
fn to_f64(self) -> f64 {
self
}
}
impl HasConstants<Self> for f64 {
const MAX: Self = Self::MAX;
const MIN: Self = -Self::MAX;
const ZERO: Self = 0.0;
const ONE: Self = 1.0;
const TWO: Self = 2.0;
}
impl<T: Number + Ord> Signum for T {
fn signum(&self) -> i32 {
match self.cmp(&T::ZERO) {
Ordering::Greater => 1,
Ordering::Less => -1,
Ordering::Equal => 0,
}
}
}
}
}
pub mod seg_trees {
pub mod lazy_seg_tree {
use std::ops::Range;
use crate::algo_lib::seg_trees::seg_tree_trait::SegTreeNode;
///
/// Segment Tree
///
#[allow(unused)]
#[derive(Clone)]
pub struct SegTree<T: SegTreeNode> {
n: usize,
tree: Vec<T>,
updates_to_push: Vec<Option<T::Update>>,
context: T::Context,
right_nodes: Vec<usize>,
}
#[allow(unused)]
impl<T: SegTreeNode> SegTree<T> {
fn pull(&mut self, v: usize, vr: usize) {
self.tree[v] = T::join_nodes(&self.tree[v + 1], &self.tree[vr], &self.context);
}
fn build(&mut self, v: usize, l: usize, r: usize, init_val: &T) {
if l + 1 == r {
self.tree[v] = init_val.clone();
} else {
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.build(v + 1, l, m, init_val);
self.build(vr, m, r, init_val);
self.pull(v, vr);
}
}
fn push(&mut self, v: usize, l: usize, r: usize) {
let update = self.updates_to_push[v].clone();
self.updates_to_push[v] = None;
match update {
None => {}
Some(update) => {
let m = (l + r) >> 1;
self.apply_update(v + 1, &update, m - l == 1);
self.apply_update(v + ((r - l) & !1), &update, r - m == 1);
}
}
}
fn get_(&mut self, v: usize, l: usize, r: usize, ql: usize, qr: usize) -> T {
assert!(qr >= l);
assert!(ql < r);
if ql <= l && r <= qr {
return self.tree[v].clone();
}
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.push(v, l, r);
let res = if ql >= m {
self.get_(vr, m, r, ql, qr)
} else if qr <= m {
self.get_(v + 1, l, m, ql, qr)
} else {
T::join_nodes(
&self.get_(v + 1, l, m, ql, qr),
&self.get_(vr, m, r, ql, qr),
&self.context,
)
};
self.pull(v, vr);
res
}
fn visit_(
&mut self,
v: usize,
l: usize,
r: usize,
ql: usize,
qr: usize,
f: &mut impl FnMut(&T),
) {
assert!(qr >= l);
assert!(ql < r);
if ql <= l && r <= qr {
f(&self.tree[v]);
return;
}
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.push(v, l, r);
if ql >= m {
self.visit_(vr, m, r, ql, qr, f);
} else if qr <= m {
self.visit_(v + 1, l, m, ql, qr, f)
} else {
self.visit_(v + 1, l, m, ql, qr, f);
self.visit_(vr, m, r, ql, qr, f);
};
self.pull(v, vr);
}
fn join_updates(current: &mut Option<T::Update>, add: &T::Update) {
match current {
None => *current = Some(add.clone()),
Some(current) => T::join_updates(current, add),
};
}
fn apply_update(&mut self, v: usize, update: &T::Update, is_leaf: bool) {
T::apply_update(&mut self.tree[v], update);
if !is_leaf {
Self::join_updates(&mut self.updates_to_push[v], update);
}
}
fn modify_(&mut self, v: usize, l: usize, r: usize, ql: usize, qr: usize, update: &T::Update) {
assert!(qr >= l);
assert!(ql < r);
if ql <= l && r <= qr {
self.apply_update(v, update, r - l == 1);
return;
}
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.push(v, l, r);
if ql >= m {
self.modify_(vr, m, r, ql, qr, update);
} else if qr <= m {
self.modify_(v + 1, l, m, ql, qr, update);
} else {
self.modify_(v + 1, l, m, ql, qr, update);
self.modify_(vr, m, r, ql, qr, update);
};
self.pull(v, vr);
}
pub fn update(&mut self, range: Range<usize>, update: T::Update) {
if range.is_empty() {
return;
}
assert!(!range.is_empty());
self.modify_(0, 0, self.n, range.start, range.end, &update);
}
pub fn update_point(&mut self, pos: usize, new_node: T) {
let mut l = 0;
let mut r = self.n;
let mut v: usize = 0;
let mut to_pull = vec![];
while r - l > 1 {
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.push(v, l, r);
to_pull.push((v, vr));
if pos < m {
r = m;
v = v + 1;
} else {
l = m;
v = vr;
}
}
self.tree[v] = new_node;
for (v, vr) in to_pull.into_iter().rev() {
self.pull(v, vr);
}
}
fn find_last_true_(
&mut self,
v: usize,
l: usize,
r: usize,
range: Range<usize>,
f: &impl Fn(&T) -> bool,
) -> Option<usize> {
if range.start >= r || l >= range.end {
return None;
}
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
if range.start <= l && r <= range.end {
if !f(&self.tree[v]) {
return None;
}
if r - l == 1 {
return Some(l);
}
}
self.push(v, l, r);
if let Some(res) = self.find_last_true_(vr, m, r, range.clone(), f) {
Some(res)
} else {
self.find_last_true_(v + 1, l, m, range, f)
}
}
// returns position
pub fn find_last_true(&mut self, range: Range<usize>, f: impl Fn(&T) -> bool) -> Option<usize> {
self.find_last_true_(0, 0, self.n, range, &f)
}
pub fn get(&mut self, range: Range<usize>) -> T {
if range.is_empty() {
return T::default();
}
self.get_(0, 0, self.n, range.start, range.end)
}
pub fn visit(&mut self, range: Range<usize>, f: &mut impl FnMut(&T)) {
if range.is_empty() {
return;
}
self.visit_(0, 0, self.n, range.start, range.end, f);
}
pub fn new_with_context(n: usize, f: impl Fn(usize) -> T, context: T::Context) -> Self {
assert!(n > 0);
let tree = vec![T::default(); 2 * n - 1];
let updates_to_push = vec![None; 2 * n - 1];
let mut res = SegTree {
n,
tree,
updates_to_push,
context,
right_nodes: vec![],
};
res.build_f(0, 0, n, &f);
res
}
pub fn new(n: usize, f: impl Fn(usize) -> T) -> Self
where
T::Context: Default,
{
assert!(n > 0);
let tree = vec![T::default(); 2 * n - 1];
let updates_to_push = vec![None; 2 * n - 1];
let mut res = SegTree {
n,
tree,
updates_to_push,
context: T::Context::default(),
right_nodes: vec![],
};
res.build_f(0, 0, n, &f);
res
}
fn build_f(&mut self, v: usize, l: usize, r: usize, f: &impl Fn(usize) -> T) {
if l + 1 == r {
self.tree[v] = f(l);
} else {
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.build_f(v + 1, l, m, f);
self.build_f(vr, m, r, f);
self.pull(v, vr);
}
}
pub fn len(&self) -> usize {
self.n
}
pub fn expert_get_node(&self, node: usize) -> &T {
&self.tree[node]
}
pub fn expert_get_left_node(&self, node: usize) -> usize {
node + 1
}
fn build_right_nodes(&mut self, v: usize, l: usize, r: usize) {
if l + 1 == r {
self.right_nodes.push(0);
} else {
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.right_nodes.push(vr);
self.build_right_nodes(v + 1, l, m);
self.build_right_nodes(vr, m, r);
}
}
// TODO: shouldn't be mut
pub fn expert_get_right_node(&mut self, node: usize) -> usize {
if self.right_nodes.is_empty() {
self.build_right_nodes(0, 0, self.n);
}
self.right_nodes[node]
}
// Used for Kinetic Seg Tree
pub fn expert_rebuild_nodes(&mut self, should_rebuild: impl Fn(&T, &T::Context) -> bool) {
self.expert_rebuild_nodes_(0, 0, self.n, &should_rebuild);
}
fn expert_rebuild_nodes_(
&mut self,
v: usize,
l: usize,
r: usize,
should_rebuild: &impl Fn(&T, &T::Context) -> bool,
) {
if r - l <= 1 || !should_rebuild(&self.tree[v], &self.context) {
return;
}
let m = (l + r) >> 1;
let vr = v + ((m - l) << 1);
self.push(v, l, r);
self.expert_rebuild_nodes_(v + 1, l, m, should_rebuild);
self.expert_rebuild_nodes_(vr, m, r, should_rebuild);
self.pull(v, vr);
}
pub fn update_context(&mut self, f: impl Fn(&mut T::Context)) {
f(&mut self.context);
}
pub fn get_context(&self) -> &T::Context {
&self.context
}
}
}
pub mod seg_tree_trait {
pub trait SegTreeNode: Clone + Default {
fn join_nodes(l: &Self, r: &Self, context: &Self::Context) -> Self;
fn apply_update(node: &mut Self, update: &Self::Update);
fn join_updates(current: &mut Self::Update, add: &Self::Update);
type Update: Clone;
type Context;
}
}
}
}
fn main() {
let input = algo_lib::io::input::Input::new_stdin();
let mut output = algo_lib::io::output::Output::new_stdout();
crate::solution::run(input, output);
}
这程序好像有点Bug,我给组数据试试?
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 2236kb
input:
6 6 6 2 1 5 9 10 15 18 2 2 1 3 3 -3 2 2 1 3 4 3 2 3 2 4
output:
1 0 2 0
result:
ok 4 number(s): "1 0 2 0"
Test #2:
score: 0
Accepted
time: 12ms
memory: 2200kb
input:
5000 5000 2 0 -329 -328 -327 -326 -325 -324 -323 -322 -321 -320 -319 -318 -317 -316 -315 -314 -313 -312 -311 -310 -309 -308 -307 -306 -305 -304 -303 -302 -301 -300 -299 -298 -297 -296 -295 -294 -293 -292 -291 -290 -289 -288 -287 -286 -285 -284 -283 -282 -281 -280 -279 -278 -277 -276 -275 -274 -273 -...
output:
2 304 73 29 61 292 139 48 17 99 6 5 53 93 3 91 65 29 33 306 21 24 17 21 281 12 16 1 33 7 18 96 7 40 39 13 7 46 43 16 1 72 33 16 22 5 6 189 27 1 35 107 43 34 3 27 20 21 44 56 96 36 2 27 22 30 32 6 5 105 27 37 12 58 2 21 154 17 110 57 3 7 33 15 24 94 68 25 1 14 10 4 10 2 25 39 36 33 164 11 19 181 11 3...
result:
ok 3337 numbers
Test #3:
score: 0
Accepted
time: 10ms
memory: 2412kb
input:
5000 5000 2 0 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 86...
output:
362 82 14 234 140 5 44 136 22 43 29 96 59 23 25 61 193 22 39 39 23 53 48 76 100 58 120 24 12 106 32 48 73 63 116 16 136 10 28 15 84 30 65 1 54 15 16 70 1 95 74 14 17 20 36 254 22 29 70 172 106 2 25 8 98 35 169 16 2 2 99 10 36 40 3 69 272 170 219 12 79 26 78 100 10 167 140 70 34 17 23 21 55 10 6 17 6...
result:
ok 3313 numbers
Test #4:
score: 0
Accepted
time: 13ms
memory: 2264kb
input:
5000 5000 2 0 -456 -455 -454 -453 -452 -451 -450 -449 -448 -447 -446 -445 -444 -443 -442 -441 -440 -439 -438 -437 -436 -435 -434 -433 -432 -431 -430 -429 -428 -427 -426 -425 -424 -423 -422 -421 -420 -419 -418 -417 -416 -415 -414 -413 -412 -411 -410 -409 -408 -407 -406 -405 -404 -403 -402 -401 -400 -...
output:
8 75 80 408 385 73 37 402 338 43 11 163 3 7 80 0 339 47 384 8 10 47 162 307 30 28 36 14 27 126 271 151 4 11 11 9 92 154 2 15 28 160 205 12 59 79 114 23 22 141 7 12 31 42 120 0 34 2 167 157 76 32 20 298 47 104 76 33 49 34 1 40 16 1 28 7 4 55 14 8 68 17 7 117 1 14 14 80 44 8 45 49 65 15 49 56 50 40 14...
result:
ok 3296 numbers
Test #5:
score: 0
Accepted
time: 82ms
memory: 12580kb
input:
200000 199999 -195 -119 -267 -146 191 -456 835 265 -226 -264 160 -101 739 -988 -967 890 -753 -854 514 491 -733 662 681 -362 804 -714 -1000 -790 931 -450 212 94 239 638 400 -167 -360 18 606 256 445 695 -509 643 -892 213 -32 42 400 733 -667 -986 225 493 -699 547 409 -35 394 920 -163 -908 -576 921 -997...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 133315 numbers
Test #6:
score: 0
Accepted
time: 85ms
memory: 12704kb
input:
200000 200000 -847 -858 977 -248 439 -318 -623 -838 -996 484 415 -888 550 940 -880 -224 95 666 -898 -36 922 346 538 858 619 771 234 909 182 -577 -399 -793 -217 -150 -805 -22 -35 -818 342 -469 -620 778 855 -156 699 464 923 935 -824 315 -156 -222 55 282 -800 -542 192 -358 -158 79 259 -57 842 -882 -690...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 133062 numbers
Test #7:
score: 0
Accepted
time: 87ms
memory: 12812kb
input:
199994 199991 -131 936 -384 633 390 191 -647 79 -481 -95 -719 -131 -225 654 392 -232 390 -520 671 440 814 95 945 -854 477 304 -29 -884 -823 -798 -386 -404 614 -875 -792 -630 875 -379 -412 -464 805 -749 952 -737 -765 -36 295 -20 571 419 -519 763 505 803 -14 307 -979 955 743 -210 159 935 499 13 -750 -...
output:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
ok 133017 numbers
Test #8:
score: 0
Accepted
time: 825ms
memory: 12816kb
input:
200000 200000 448 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
output:
5388 1796 9803 17353 10388 6660 29833 1132 10416 3492 28995 2953 5964 9845 4293 158 931 30 224 7765 7894 2412 21159 21128 8630 4778 3830 1241 3750 795 5013 529 2176 2266 566 194 2702 4520 2348 1577 6922 372 895 667 650 5530 8798 670 2806 2395 1525 4602 1558 1278 1635 5413 2804 1167 731 3000 1663 529...
result:
ok 79952 numbers
Test #9:
score: 0
Accepted
time: 1228ms
memory: 7264kb
input:
100000 100000 2 0 -866 890 -406 10 512 859 494 362 -955 -475 128 553 -986 -885 763 77 449 310 787 -656 -204 -709 -270 76 -267 184 170 -985 33 -822 666 418 26 -247 898 -104 85 -146 980 631 359 908 -560 -744 -764 836 -103 -531 -116 316 681 -148 226 206 -439 -961 -792 598 -629 -705 -479 -494 -169 608 -...
output:
5945 19533 15508 14075 35558 23781 46506 34124 44894 32242 34480 43972 45792 39812 30588 7998 25358 22005 11197 3273 43673 14284 5162 25652 32519 16639 7967 34906 3142 24285 20597 39451 13542 33435 0 34534 39229 7380 45632 11415 30503 29542 7808 18077 18828 87 32329 44233 34055 21021 41973 33289 799...
result:
ok 99900 numbers
Test #10:
score: 0
Accepted
time: 3098ms
memory: 12672kb
input:
200000 200000 2 0 -866 890 -406 10 512 859 494 362 -955 -475 128 553 -986 -885 763 77 449 310 787 -656 -204 -709 -270 76 -267 184 170 -985 33 -822 666 418 26 -247 898 -104 85 -146 980 631 359 908 -560 -744 -764 836 -103 -531 -116 316 681 -148 226 206 -439 -961 -792 598 -629 -705 -479 -494 -169 608 -...
output:
5945 19533 79394 80827 35558 71121 46506 34124 44894 32242 34480 43972 49110 55090 30588 86904 69544 72897 11197 91629 43673 80618 5162 69250 32519 78263 86935 59996 3142 24285 20597 55451 81360 61467 96742 60368 55673 87522 45632 83487 30503 65360 7808 18077 76074 87 62573 44233 34055 21021 41973 3...
result:
ok 199800 numbers
Extra Test:
score: 0
Extra Test Passed