Skip to content

Commit c524def

Browse files
authored
Merge pull request #57 from qryxip/ja-all-enabled-more-examples
More examples
2 parents 94119e8 + 90e66d3 commit c524def

38 files changed

+2128
-46
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ jobs:
2929
with:
3030
toolchain: ${{ matrix.channel }}-x86_64-unknown-linux-gnu
3131
override: true
32-
profile: default
32+
profile: minimal
33+
components: rustfmt
3334

3435
- name: '`cargo fmt -- --check`'
3536
uses: actions-rs/cargo@v1
@@ -103,7 +104,8 @@ jobs:
103104
with:
104105
toolchain: ${{ matrix.toolchain }}
105106
override: true
106-
profile: default
107+
profile: minimal
108+
components: clippy
107109

108110
- name: Setup Python 3.8
109111
uses: actions/setup-python@v1

examples/abc122-c.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// https://atcoder.jp/contests/abc122/tasks/abc122_c
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `itertools-num`
6+
// - `proconio`
7+
8+
use itertools_num::ItertoolsNum as _;
9+
use proconio::marker::{Bytes, Usize1};
10+
use proconio::{fastout, input};
11+
12+
use std::iter;
13+
14+
// `#[proconio::fastout]`で`println!`を置き換える。
15+
//
16+
// https://docs.rs/proconio-derive/0.1/proconio_derive/attr.fastout.html
17+
#[fastout]
18+
fn main() {
19+
// `proconio::input!`では使わない値を`_`とすることができる。
20+
//
21+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
22+
input! {
23+
_: usize,
24+
q: usize,
25+
s: Bytes,
26+
lrs: [(Usize1, Usize1); q],
27+
}
28+
29+
// `<_ as itertools_num::ItertoolsNum>::cumsum`で作られた一次元累積和のイテレータを、先頭に`0`を挿入した上で`Vec<_>`にする。
30+
//
31+
// https://docs.rs/itertools-num/0.1/itertools_num/trait.ItertoolsNum.html#method.cumsum
32+
let cumsum = iter::once(0)
33+
.chain(s.windows(2).map(|w| (w == b"AC").into()))
34+
.cumsum()
35+
.collect::<Vec<u32>>();
36+
37+
for (l, r) in lrs {
38+
println!("{}", cumsum[r] - cumsum[l]);
39+
}
40+
}

examples/abc143-d.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// https://atcoder.jp/contests/abc143/tasks/abc143_d
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `itertools`
6+
// - `proconio`
7+
// - `superslice`
8+
9+
use itertools::Itertools as _;
10+
use proconio::input;
11+
use superslice::Ext as _;
12+
13+
fn main() {
14+
// `proconio::input!`。
15+
//
16+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
17+
input! {
18+
mut ls: [u64],
19+
}
20+
21+
ls.sort();
22+
23+
// aとbのnC2通りの組み合わせを`<_ as itertools::Itertools>::tuple_combinations`を使って添字付きで列挙。
24+
// そしてa, bに対するcの最小値の位置を`<[u64] as superslice::Ext>::upper_bound`で求め、bの位置との差を数え上げたものを答えとする。
25+
// そのようなcが存在しないとき、`ls[..i].upper_bound(..)`は(C++と同じように)`i`を返すので数える対象は減算により`0`になる。
26+
//
27+
// https://docs.rs/itertools/0.8/itertools/trait.Itertools.html#method.tuple_combinations
28+
// https://docs.rs/superslice/1/superslice/trait.Ext.html#tymethod.upper_bound
29+
let ans = ls
30+
.iter()
31+
.enumerate()
32+
.tuple_combinations()
33+
.map(|((i, b), (_, a))| i - ls[..i].upper_bound(&(a - b)))
34+
.sum::<usize>();
35+
println!("{}", ans);
36+
}

examples/abc145-c.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// https://atcoder.jp/contests/abc145/tasks/abc145_c
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `itertools`
6+
// - `nalgebra`
7+
// - `proconio`
8+
9+
use itertools::Itertools as _;
10+
use nalgebra::{Point2, Scalar};
11+
use proconio::input;
12+
use proconio::source::{Readable, Source};
13+
14+
use std::convert::Infallible;
15+
use std::io::BufRead;
16+
use std::marker::PhantomData;
17+
18+
fn main() {
19+
// `proconio::input!`。
20+
//
21+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
22+
input! {
23+
n: usize,
24+
points: [ReadPoint2<f64>; n],
25+
}
26+
27+
// nC2通りの組み合わせを列挙するのに`<_ as itertools::Itertools>::tuple_combinations`を用いる。
28+
// また各点同士の距離√((x_i - x_j)^2 + (y_i - y_j)^2)を求めるのに`nalgebra::distance`を使う。
29+
//
30+
// https://docs.rs/itertools/0.8/itertools/trait.Itertools.html#method.tuple_combinations
31+
// https://docs.rs/nalgebra/0.19/nalgebra/fn.distance.html
32+
let ans = 2.0 / (n as f64)
33+
* points
34+
.into_iter()
35+
.tuple_combinations()
36+
.map(|(p1, p2)| nalgebra::distance(&p1, &p2))
37+
.sum::<f64>();
38+
println!("{}", ans);
39+
}
40+
41+
// `proconio::source::Readable`を実装することで`Usize1`のようなマーカー型を作ることができる。
42+
//
43+
// https://docs.rs/proconio/0.3.6/proconio/source/trait.Readable.html
44+
45+
struct ReadPoint2<T>(Infallible, PhantomData<fn() -> T>);
46+
47+
impl<N: Readable<Output = N> + Scalar> Readable for ReadPoint2<N> {
48+
type Output = Point2<N>;
49+
50+
fn read<R: BufRead, S: Source<R>>(source: &mut S) -> Point2<N> {
51+
Point2::new(N::read(source), N::read(source))
52+
}
53+
}

examples/abc154-d.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// https://atcoder.jp/contests/abc154/tasks/abc154_d
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `itertools-num`
6+
// - `ordered-float`
7+
// - `proconio`
8+
9+
use itertools_num::ItertoolsNum as _;
10+
use ordered_float::NotNan;
11+
use proconio::input;
12+
13+
use std::iter;
14+
15+
// `NotNan<f64>: FromStr`であり、四則演算の右辺に`f64`が許されているので`NotNan`のリテラルが必要になることは少ない。
16+
// 必要な場合このようなマクロや関数等を用意しておくと見た目は軽くなる。
17+
macro_rules! notnan(($lit:literal) => (NotNan::new($lit).unwrap()));
18+
19+
fn main() {
20+
// `proconio::input!`は(オリジナルの`input!`もそうだが)`FromStr`を実装する値なら何でも読める。
21+
// ここでは{ p_i }を`ordered_float::NotNan<f64>`として受け取る。
22+
//
23+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
24+
// https://docs.rs/ordered-float/1/ordered_float/struct.NotNan.html
25+
input! {
26+
n: usize,
27+
k: usize,
28+
ps: [NotNan<_>; n],
29+
}
30+
31+
// 先頭に`0`を挿入した一次元累積和のイテレータを`<_ as itertools_num::ItertoolsNum>::cumsum`で作り、`Vec<_>`にする。
32+
//
33+
// https://docs.rs/itertools-num/0.1/itertools_num/trait.ItertoolsNum.html#method.cumsum
34+
let ans = iter::once(notnan!(0.0))
35+
.chain(ps.into_iter().map(|p| (p + 1.0) / 2.0))
36+
.cumsum()
37+
.collect::<Vec<NotNan<_>>>()
38+
.windows(k + 1)
39+
.map(|w| w[w.len() - 1] - w[0])
40+
.max()
41+
.unwrap();
42+
println!("{}", ans);
43+
}

examples/abc154-e.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// https://atcoder.jp/contests/abc154/tasks/abc154_e
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `num`
6+
// - `proconio`
7+
8+
use proconio::input;
9+
use proconio::marker::Bytes;
10+
11+
fn main() {
12+
// http://drken1215.hatenablog.com/entry/2020/02/09/225300
13+
14+
// `proconio::input!`。
15+
//
16+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
17+
input! {
18+
n: Bytes,
19+
k: usize,
20+
}
21+
22+
let n = n.into_iter().map(|d| (d - b'0').into()).collect();
23+
24+
println!("{}", St { n }.solve(0, k, false));
25+
26+
struct St {
27+
n: Vec<usize>,
28+
}
29+
30+
impl St {
31+
fn solve(&self, i: usize, j: usize, p: bool) -> usize {
32+
let Self { n } = self;
33+
34+
if j == 0 {
35+
1
36+
} else if i == n.len() {
37+
0
38+
} else if p {
39+
// 配列でのDPと違い、ここで打ち切れる。 ここで`num_integer::binomial`が使える。
40+
//
41+
// https://docs.rs/num-integer/0.1/num_integer/fn.binomial.html
42+
num::integer::binomial(n.len() - i, j) * 9usize.pow(j as u32)
43+
} else if n[i] == 0 {
44+
self.solve(i + 1, j, false)
45+
} else {
46+
self.solve(i + 1, j, true)
47+
+ self.solve(i + 1, j - 1, true) * (n[i] - 1)
48+
+ self.solve(i + 1, j - 1, false)
49+
}
50+
}
51+
}
52+
}

examples/abc156-d.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// https://atcoder.jp/contests/abc156/tasks/abc156_d
2+
//
3+
// 以下のクレートを使用。
4+
//
5+
// - `num`
6+
// - `num-traits`
7+
use num::One;
8+
use proconio::input;
9+
10+
use std::fmt::{self, Display};
11+
use std::num::ParseIntError;
12+
use std::ops::{Add, Div, Mul, MulAssign, Sub};
13+
use std::str::FromStr;
14+
15+
fn main() {
16+
// `proconio::input!`。
17+
//
18+
// https://docs.rs/proconio/0.3.6/proconio/macro.input.html
19+
input! {
20+
n: Zp,
21+
a: Zp,
22+
b: Zp,
23+
}
24+
25+
// `num_traits::pow`を使って2^nを求める。
26+
//
27+
// https://docs.rs/num-traits/0.2/num_traits/pow/fn.pow.html
28+
let ans = num::pow(Zp::new(2), n.repr) - binomial(n, a) - binomial(n, b) - Zp::new(1);
29+
println!("{}", ans);
30+
}
31+
32+
fn binomial(n: Zp, k: Zp) -> Zp {
33+
let (mut numer, mut denom) = (n, Zp::new(1));
34+
for i in 2..=k.repr {
35+
numer *= n - Zp::new(i) + Zp::new(1);
36+
denom *= Zp::new(i);
37+
}
38+
numer / denom
39+
}
40+
41+
const P: usize = 1_000_000_007;
42+
43+
#[derive(Debug, Clone, Copy)]
44+
struct Zp {
45+
repr: usize,
46+
}
47+
48+
impl Zp {
49+
fn new(val: usize) -> Self {
50+
Self { repr: val % P }
51+
}
52+
}
53+
54+
impl FromStr for Zp {
55+
type Err = ParseIntError;
56+
57+
fn from_str(s: &str) -> Result<Self, ParseIntError> {
58+
s.parse().map(Self::new)
59+
}
60+
}
61+
62+
// `num_integer::pow`に必要。
63+
impl One for Zp {
64+
fn one() -> Self {
65+
Self { repr: 1 }
66+
}
67+
}
68+
69+
impl Add for Zp {
70+
type Output = Self;
71+
72+
fn add(self, rhs: Self) -> Self {
73+
Self::new(self.repr + rhs.repr)
74+
}
75+
}
76+
77+
impl Sub for Zp {
78+
type Output = Self;
79+
80+
fn sub(self, rhs: Self) -> Self {
81+
let repr = if self.repr < rhs.repr {
82+
P + self.repr - rhs.repr
83+
} else {
84+
self.repr - rhs.repr
85+
};
86+
Self { repr }
87+
}
88+
}
89+
90+
impl Mul for Zp {
91+
type Output = Self;
92+
93+
fn mul(self, rhs: Self) -> Self {
94+
Self::new(self.repr * rhs.repr)
95+
}
96+
}
97+
98+
impl MulAssign for Zp {
99+
fn mul_assign(&mut self, rhs: Self) {
100+
*self = *self * rhs;
101+
}
102+
}
103+
104+
impl Div for Zp {
105+
type Output = Self;
106+
107+
fn div(self, rhs: Self) -> Self {
108+
// Fermatの小定理より。
109+
// `num_integer::Integer::extended_gcd`というのもあるのでこれを使っても良い。
110+
self * num::pow(rhs, P - 2)
111+
}
112+
}
113+
114+
impl Display for Zp {
115+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
116+
Display::fmt(&self.repr, fmt)
117+
}
118+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy