Skip to content

Commit 380433a

Browse files
committed
Refactoring
1 parent d5f51f0 commit 380433a

File tree

11 files changed

+438
-630
lines changed

11 files changed

+438
-630
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22
name = "competitive"
33
version = "0.1.0"
44
authors = ["Hideyuki Tanaka <[email protected]>"]
5+
edition = "2018"
56

67
[dependencies]
8+
proconio = "0.3"

examples/atc001_b.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
extern crate competitive;
2-
3-
#[macro_use]
4-
use competitive::*;
1+
use competitive::prelude::*;
2+
use competitive::union_find::*;
53

64
fn main() {
75
// let ss = io::read_string();
@@ -10,13 +8,13 @@ fn main() {
108
// let q: usize = sc.next();
119
// let qs: Vec<(i32, usize, usize)> = (0..q).map(|_| (sc.next(), sc.next(), sc.next())).collect();
1210

13-
input!{
11+
input! {
1412
n: usize,
1513
q: usize,
1614
qs: [(i32, usize, usize); q],
1715
}
1816

19-
let mut uf = union_find::UnionFind::new(n);
17+
let mut uf = UnionFind::new(n);
2018
for (p, a, b) in qs {
2119
if p == 0 {
2220
uf.union(a, b);

examples/bench.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
extern crate competitive;
2-
3-
#[macro_use]
4-
use competitive::*;
1+
use competitive::prelude::*;
52

63
fn main() {
7-
input!{
4+
input! {
85
n: usize,
96
v: [usize; n],
107
}

src/binary_search.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pub fn binary_search(mut ok: i64, mut ng: i64, pred: impl Fn(i64) -> bool) -> i64 {
2+
while (ok - ng).abs() > 1 {
3+
let mi = (ok + ng) / 2;
4+
if pred(mi) {
5+
ok = mi;
6+
} else {
7+
ng = mi;
8+
}
9+
}
10+
ok
11+
}
12+
13+
#[test]
14+
fn binary_search_test() {
15+
let v = [1, 2, 3, 4, 5];
16+
assert_eq!(3, binary_search(v.len() as _, -1, |i| v[i as usize] > 3));
17+
assert_eq!(5, binary_search(v.len() as _, -1, |i| v[i as usize] > 100));
18+
assert_eq!(0, binary_search(v.len() as _, -1, |i| v[i as usize] > 0));
19+
}

src/graph.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use std::cmp::min;
2+
use std::collections::VecDeque;
3+
4+
pub fn visit(
5+
g: &Vec<Vec<usize>>,
6+
v: usize,
7+
scc: &mut Vec<Vec<usize>>,
8+
s: &mut VecDeque<usize>,
9+
ins: &mut Vec<bool>,
10+
low: &mut Vec<usize>,
11+
num: &mut Vec<usize>,
12+
time: usize,
13+
) {
14+
low[v] = time;
15+
num[v] = time;
16+
17+
s.push_back(v);
18+
ins[v] = true;
19+
20+
for &e in g[v].iter() {
21+
let w = e;
22+
if num[w] == 0 {
23+
visit(g, w, scc, s, ins, low, num, time + 1);
24+
low[v] = min(low[v], low[w]);
25+
} else if ins[w] {
26+
low[v] = min(low[v], num[w]);
27+
}
28+
}
29+
30+
if low[v] == num[v] {
31+
let mut c = vec![];
32+
loop {
33+
let w = s.pop_back().unwrap();
34+
ins[w] = false;
35+
c.push(w);
36+
if v == w {
37+
break;
38+
}
39+
}
40+
scc.push(c);
41+
}
42+
}
43+
44+
pub fn strongly_connected_components(g: &Vec<Vec<usize>>) -> Vec<Vec<usize>> {
45+
let n = g.len();
46+
47+
let mut num = vec![0; n];
48+
let mut low = vec![0; n];
49+
let mut s = VecDeque::new();
50+
let mut ins = vec![false; n];
51+
let mut scc = vec![];
52+
53+
for u in 0..n {
54+
if num[u] == 0 {
55+
visit(g, u, &mut scc, &mut s, &mut ins, &mut low, &mut num, 1);
56+
}
57+
}
58+
59+
scc
60+
}

src/inf.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use std::cmp::min;
2+
use std::ops::Add;
3+
4+
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
5+
pub enum Inf<T> {
6+
NotInf(T),
7+
Inf,
8+
}
9+
10+
use self::Inf::*;
11+
12+
impl<T> From<T> for Inf<T> {
13+
fn from(v: T) -> Self {
14+
Inf::NotInf(v)
15+
}
16+
}
17+
18+
impl<T: Add<Output = T>> Add for Inf<T> {
19+
type Output = Inf<T>;
20+
fn add(self, rhs: Self) -> Self {
21+
match (self, rhs) {
22+
(NotInf(a), NotInf(b)) => NotInf(a + b),
23+
_ => Inf,
24+
}
25+
}
26+
}
27+
28+
impl<T: Add<Output = T>> Add<T> for Inf<T> {
29+
type Output = Inf<T>;
30+
fn add(self, rhs: T) -> Self {
31+
match self {
32+
NotInf(a) => NotInf(a + rhs),
33+
_ => Inf,
34+
}
35+
}
36+
}
37+
38+
impl<T: Clone + Ord> Inf<T> {
39+
pub fn min_assign(&mut self, rhs: Self) {
40+
*self = min(self.clone(), rhs);
41+
}
42+
}

src/io.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use std::io::Read;
2+
use std::str::FromStr;
3+
4+
/// Input scanner
5+
///
6+
/// # Examples
7+
///
8+
/// ```
9+
/// # use competitive::io::*;
10+
/// let mut sc = Scanner::new("1 3.14 Hello");
11+
/// assert_eq!(sc.next::<i32>(), 1);
12+
/// assert_eq!(sc.next::<f64>(), 3.14);
13+
/// assert_eq!(sc.next::<String>(), "Hello");
14+
/// ```
15+
pub struct Scanner<'a> {
16+
iter: std::str::SplitWhitespace<'a>,
17+
}
18+
19+
impl<'a> Scanner<'a> {
20+
pub fn new(s: &'a str) -> Scanner<'a> {
21+
Scanner {
22+
iter: s.split_whitespace(),
23+
}
24+
}
25+
26+
pub fn next<T: FromStr>(&mut self) -> T {
27+
let s = self.iter.next().unwrap();
28+
if let Ok(v) = s.parse::<T>() {
29+
v
30+
} else {
31+
panic!("Parse error")
32+
}
33+
}
34+
35+
pub fn next_vec_len<T: FromStr>(&mut self) -> Vec<T> {
36+
let n: usize = self.next();
37+
self.next_vec(n)
38+
}
39+
40+
pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
41+
(0..n).map(|_| self.next()).collect()
42+
}
43+
}
44+
45+
pub fn read_string() -> String {
46+
let mut s = String::new();
47+
std::io::stdin().read_to_string(&mut s).unwrap();
48+
s
49+
}
50+
51+
pub fn read_line() -> String {
52+
let mut s = String::new();
53+
std::io::stdin().read_line(&mut s).unwrap();
54+
s.trim_end().to_owned()
55+
}

0 commit comments

Comments
 (0)