Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 90e66d3

Browse files
committed
Add an example for ABC168-E
1 parent 69a4c44 commit 90e66d3

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

examples/abc168-e.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// https://atcoder.jp/contests/abc168/tasks/abc168_e
2+
//
3+
// 以下のクレートを使用。
4+
// - `maplit`
5+
// - `num`
6+
// - `num-rational`
7+
// - `proconio`
8+
9+
use maplit::hashmap;
10+
use num::{rational::Ratio, One, Signed as _};
11+
use proconio::input;
12+
use std::{
13+
fmt,
14+
iter::Product,
15+
ops::{Add, Mul, Sub},
16+
};
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+
abs: [(i64, i64); n],
25+
}
26+
27+
// 有理数として`num_rational::Ratio<i64>`を使う。
28+
//
29+
// https://docs.rs/num-rational/0.2.4/num_rational/struct.Ratio.html
30+
31+
let mut zeros = 0;
32+
let mut horz = 0;
33+
let mut vert = 0;
34+
let mut others = hashmap!();
35+
36+
for (a, b) in abs {
37+
match (a.signum(), b.signum()) {
38+
(0, 0) => zeros += 1,
39+
(1, 0) | (-1, 0) => horz += 1,
40+
(0, 1) | (0, -1) => vert += 1,
41+
_ => *others.entry(Ratio::new(a, b)).or_insert(0) += 1usize,
42+
}
43+
}
44+
45+
let ans = others
46+
.iter()
47+
.map(|(grad, &num1)| {
48+
// `Ratio::recip`で逆元を得ることができる。
49+
//
50+
// https://docs.rs/num-rational/0.2.4/num_rational/struct.Ratio.html#method.recip
51+
let num2 = *others.get(&-grad.recip()).unwrap_or(&0);
52+
if grad.is_negative() && num2 > 0 {
53+
Zp::unchecked(1)
54+
} else {
55+
xor_combinations(num1, num2)
56+
}
57+
})
58+
.product::<Zp>()
59+
* xor_combinations(horz, vert)
60+
+ Zp::unchecked(zeros)
61+
- Zp::unchecked(1);
62+
println!("{}", ans);
63+
}
64+
65+
fn xor_combinations(a: usize, b: usize) -> Zp {
66+
return pow2(a) + pow2(b) - Zp::unchecked(1);
67+
68+
fn pow2(exp: usize) -> Zp {
69+
num::pow(Zp::unchecked(2), exp)
70+
}
71+
}
72+
73+
const P: usize = 1_000_000_007;
74+
75+
#[derive(Clone, Copy, Debug)]
76+
struct Zp {
77+
repr: usize,
78+
}
79+
80+
impl Zp {
81+
fn new(val: usize) -> Self {
82+
Self { repr: val % P }
83+
}
84+
85+
fn unchecked(repr: usize) -> Self {
86+
Self { repr }
87+
}
88+
}
89+
90+
impl One for Zp {
91+
fn one() -> Self {
92+
Self::unchecked(1)
93+
}
94+
}
95+
96+
impl fmt::Display for Zp {
97+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
98+
fmt::Display::fmt(&self.repr, fmt)
99+
}
100+
}
101+
102+
impl Add for Zp {
103+
type Output = Self;
104+
105+
fn add(self, rhs: Self) -> Self {
106+
Self::new(self.repr + rhs.repr)
107+
}
108+
}
109+
110+
impl Sub for Zp {
111+
type Output = Self;
112+
113+
fn sub(self, rhs: Self) -> Self {
114+
Self::new(P + self.repr - rhs.repr)
115+
}
116+
}
117+
118+
impl Mul for Zp {
119+
type Output = Self;
120+
121+
fn mul(self, rhs: Self) -> Self {
122+
Self::new(self.repr * rhs.repr)
123+
}
124+
}
125+
126+
impl Product for Zp {
127+
fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
128+
iter.fold(Self::unchecked(1), Mul::mul)
129+
}
130+
}

test-examples.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,13 @@ url = "https://atcoder.jp/contests/abc168/tasks/abc168_c"
268268
matching = { FloatOr = { abs = 1e-9, rel = 1e-9 } }
269269
meta = { using = ["num", "proconio"] }
270270

271+
[examples.abc168-e]
272+
type = "Normal"
273+
name = "ABC168 - E - ∙ (Bullet)"
274+
url = "https://atcoder.jp/contests/abc168/tasks/abc168_e"
275+
matching = "Words"
276+
meta = { using = ["maplit", "num", "proconio"] }
277+
271278
[examples.agc020-c]
272279
type = "Normal"
273280
name = "AGC020: C - Median Sum"

0 commit comments

Comments
 (0)