Skip to content

Commit 2b3809e

Browse files
committed
Add a test for ABC129-F
1 parent a30b072 commit 2b3809e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+248
-0
lines changed

examples/abc129-f.rs

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// https://atcoder.jp/contests/abc129/tasks/abc129_f
2+
3+
use derive_more::{Display, FromStr};
4+
use ndarray::{array, Array2, LinalgScalar};
5+
use num::integer::ExtendedGcd;
6+
use num::{CheckedDiv, Integer as _, One, PrimInt, Unsigned, Zero};
7+
8+
use std::cell::Cell;
9+
use std::cmp;
10+
use std::convert::{TryFrom as _, TryInto as _};
11+
use std::ops::{Add, Div, Mul, Sub};
12+
13+
fn main() {
14+
// use std::io::{self, Read as _};
15+
//
16+
// let mut input = "".to_owned();
17+
// io::stdin().read_to_string(&mut input).unwrap();
18+
// let mut input = input.split_whitespace();
19+
// macro_rules! read {
20+
// ([$t:tt; $n:expr]) => {
21+
// (0..$n).map(|_| read!($t)).collect::<Vec<_>>()
22+
// };
23+
// (($($t:tt),+)) => {
24+
// ($(read!($t)),*)
25+
// };
26+
// (_1based) => {
27+
// read!(usize) - 1
28+
// };
29+
// (_bytes) => {
30+
// read!(String).into_bytes()
31+
// };
32+
// ($ty:ty) => {
33+
// input.next().unwrap().parse::<$ty>().unwrap()
34+
// };
35+
// }
36+
//
37+
// let (l, a, b, m) = read!((u64, u64, u64, u64));
38+
39+
use proconio::input;
40+
41+
input! {
42+
l: u64,
43+
a: u64,
44+
b: u64,
45+
m: u64,
46+
}
47+
48+
MOD.with(|cell| cell.set(m));
49+
50+
let count = |d: u32| -> _ {
51+
let count = |sup: u64| cmp::min((cmp::max(sup, a + 1) - a - 1) / b + u64::from(b < sup), l);
52+
count(10u64.pow(d)) - count(10u64.pow(d) / 10)
53+
};
54+
55+
let ans = (1..=18).fold(array![[Z::new(0), Z::new(a), Z::new(1)]], |acc, d| {
56+
acc.dot(
57+
&array![
58+
[Z::new(10u64.pow(d)), Z::new(0), Z::new(0)],
59+
[Z::new(1), Z::new(1), Z::new(0)],
60+
[Z::new(0), Z::new(b), Z::new(1)],
61+
]
62+
.matrix_power(count(d)),
63+
)
64+
})[(0, 0)];
65+
println!("{}", ans);
66+
}
67+
68+
trait Array2Ext {
69+
fn matrix_power<E: PrimInt + Unsigned>(&self, exp: E) -> Self;
70+
}
71+
72+
impl<S: LinalgScalar> Array2Ext for Array2<S> {
73+
fn matrix_power<E: PrimInt + Unsigned>(&self, exp: E) -> Self {
74+
let (mut base, mut exp, mut acc) = (self.clone(), exp, Self::eye(self.nrows()));
75+
while exp > E::zero() {
76+
if (exp & E::one()) == E::one() {
77+
acc = acc.dot(&base);
78+
}
79+
exp = exp / (E::one() + E::one());
80+
base = base.dot(&base);
81+
}
82+
acc
83+
}
84+
}
85+
86+
thread_local! {
87+
static MOD: Cell<u64> = Cell::new(0);
88+
}
89+
90+
#[derive(FromStr, Display, Debug, Clone, Copy)]
91+
struct Z {
92+
repr: u64,
93+
}
94+
95+
impl Z {
96+
fn new(mut val: u64) -> Self {
97+
let modulus = MOD.with(Cell::get);
98+
if val >= modulus {
99+
val %= modulus;
100+
}
101+
Self { repr: val }
102+
}
103+
}
104+
105+
impl Zero for Z {
106+
fn zero() -> Self {
107+
Self { repr: 0 }
108+
}
109+
110+
fn is_zero(&self) -> bool {
111+
self.repr == 0
112+
}
113+
}
114+
115+
impl One for Z {
116+
fn one() -> Self {
117+
Self { repr: 1 }
118+
}
119+
}
120+
121+
impl Add for Z {
122+
type Output = Self;
123+
124+
fn add(self, rhs: Self) -> Self {
125+
Self::new(self.repr + rhs.repr)
126+
}
127+
}
128+
129+
impl Sub for Z {
130+
type Output = Self;
131+
132+
fn sub(self, rhs: Self) -> Self {
133+
debug_assert!(false, "really necessary?");
134+
135+
let repr = if self.repr < rhs.repr {
136+
MOD.with(Cell::get) + self.repr - rhs.repr
137+
} else {
138+
self.repr - rhs.repr
139+
};
140+
Self { repr }
141+
}
142+
}
143+
144+
impl Mul for Z {
145+
type Output = Self;
146+
147+
fn mul(self, rhs: Self) -> Self {
148+
Self::new(self.repr * rhs.repr)
149+
}
150+
}
151+
152+
impl Div for Z {
153+
type Output = Self;
154+
155+
fn div(self, rhs: Self) -> Self {
156+
debug_assert!(false, "really necessary?");
157+
158+
self.checked_div(&rhs)
159+
.unwrap_or_else(|| panic!("could not divide {} by {}", self, rhs))
160+
}
161+
}
162+
163+
impl CheckedDiv for Z {
164+
fn checked_div(&self, rhs: &Self) -> Option<Self> {
165+
let lhs = i64::try_from(self.repr).unwrap();
166+
let rhs = i64::try_from(rhs.repr).unwrap();
167+
let modulus = i64::try_from(MOD.with(Cell::get)).unwrap();
168+
let ExtendedGcd { gcd, x, .. } = rhs.extended_gcd(&modulus);
169+
match lhs % gcd {
170+
0 => Some(Self::new((lhs * (x + modulus)).try_into().unwrap())),
171+
_ => None,
172+
}
173+
}
174+
}

examples/tests.ron

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@
4343
name: "ABC120: D - Decayed Bridges",
4444
matching: ExactWords,
4545
),
46+
"abc129-f": (
47+
name: "ABC129: F - Takahashi's Basics in Education and Learning",
48+
matching: ExactWords,
49+
),
4650
"abc142-d": (
4751
name: "ABC124: D - Disjoint Set of Common Divisors",
4852
matching: ExactWords,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5 3 4 10007
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
4 8 1 1000000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
107 10000000000007 1000000000000007 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2500000000000 4 4 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
99982444353 100 4 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
333333333333333333 3 3 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1 999999999999999999 999999999999999999 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
998244353 629149506971940504 319836804 14876851
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
999918203 4248 723308865 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
100000000000 6 231 25200
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
999999999999999999 1 1 1000000000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
11837588 221218607 84473754642 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
81074056293 7047569542 12261087 29999997
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
999999999999999999 1 1 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
328613923524538 40980 3031 999999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
10914883567412 1570 62840 99999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1448057007031098 11 690 881005587
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
74358445905354 29310 13448 147413419
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
120900801167206 994 8061 387420489
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1380800559 8 721124722 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
105301221317 8 9457145 999999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
53562851 12672052437647 18553359394 99999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7343 44375369427231 136194167038156 841293953
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
234481 8715183188079 4262710627175 9999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
335 2647488178484 2976541338296614 999918169
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2508131942730888 5 397 387420489
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
151407055 44693807224027 6603923461 1000000000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
17544042820 3 56987735 387420489
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
355391 6022223566881 25138147452 999958020
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
18 912087068546306627 3164574410046630 996674566
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
31940 139378099479290043 26943708742238 1000000000
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
345 493299812499659259 1418510335032035 998244353
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3776 494095262613235502 19199433662734 999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
461491 67429808854595636 2017247872269 276712227
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
147 4222724580641548 6588820255446743 982883281
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5563
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
891011
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
39122908
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
900161126
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
658481246
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
521296277
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
716070897
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9086340
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
822961451
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
12975
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
999999999
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
739823859
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7215183
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
795127085
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
222138048
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
96844045
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
257000862
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
55813670
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
109152748
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
932512687
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
976788549
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
84300371
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
336830166
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
699837
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
184277614
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
357790932
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
878717921
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
207193062
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
336284961
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
564963471
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
997629525
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
390889114
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
792884
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
203043563
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
887967106

0 commit comments

Comments
 (0)