Skip to content

Commit 0b05c4a

Browse files
committed
Add an example for ABC156-D
1 parent a58bdd1 commit 0b05c4a

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

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+
}

test-examples.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ url = "https://atcoder.jp/contests/abc154/tasks/abc154_e"
177177
matching = "Words"
178178
meta = { using = ["num", "proconio"] }
179179

180+
[examples.abc156-d]
181+
type = "Normal"
182+
name = "ABC156: D - Bouquet"
183+
url = "https://atcoder.jp/contests/abc156/tasks/abc156_d"
184+
matching = "Words"
185+
meta = { using = ["num", "proconio"] }
186+
180187
[examples.agc023-a]
181188
type = "Normal"
182189
name = "AGC023: A - Zero-Sum Ranges"

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