diff --git a/atcoder/abc378/a.rs b/atcoder/abc378/a.rs new file mode 100644 index 00000000..064f9850 --- /dev/null +++ b/atcoder/abc378/a.rs @@ -0,0 +1,46 @@ +use std::collections::*; +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +fn main() { + input! { + a: [i32; 4], + } + let mut hm = HashMap::new(); + for a in a { + *hm.entry(a).or_insert(0) += 1; + } + let mut ans = 0; + for (_, v) in hm { + ans += v / 2; + } + println!("{}", ans); +} diff --git a/atcoder/abc378/b.rs b/atcoder/abc378/b.rs new file mode 100644 index 00000000..ad8e5d5b --- /dev/null +++ b/atcoder/abc378/b.rs @@ -0,0 +1,50 @@ +use std::io::{Write, BufWriter}; +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, ( $($t:tt),* )) => { ($(read_value!($next, $t)),*) }; + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, usize1) => (read_value!($next, usize) - 1); + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +fn main() { + let out = std::io::stdout(); + let mut out = BufWriter::new(out.lock()); + macro_rules! puts {($($format:tt)*) => (let _ = write!(out,$($format)*););} + input! { + n: usize, + qr: [(i64, i64); n], + q: usize, + td: [(usize1, i64); q], + } + for (t, d) in td { + let (q, r) = qr[t]; + let x = (d + q - r - 1) / q; + puts!("{}\n", x * q + r); + } +} diff --git a/atcoder/abc378/c.rs b/atcoder/abc378/c.rs new file mode 100644 index 00000000..2e714619 --- /dev/null +++ b/atcoder/abc378/c.rs @@ -0,0 +1,56 @@ +use std::collections::*; +use std::io::{Write, BufWriter}; +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +fn main() { + let out = std::io::stdout(); + let mut out = BufWriter::new(out.lock()); + macro_rules! puts {($($format:tt)*) => (let _ = write!(out,$($format)*););} + macro_rules! putvec { + ($v:expr) => { + for i in 0..$v.len() { + puts!("{}{}", $v[i], if i + 1 == $v.len() {"\n"} else {" "}); + } + } + } + input! { + n: usize, + a: [i64; n], + } + let mut hm = HashMap::new(); + let mut b = vec![0; n]; + for i in 0..n { + b[i] = hm.get(&a[i]).map_or(-1, |x| *x); + hm.insert(a[i], i as i64 + 1); + } + putvec!(b); +} diff --git a/atcoder/abc378/d.rs b/atcoder/abc378/d.rs new file mode 100644 index 00000000..f178d167 --- /dev/null +++ b/atcoder/abc378/d.rs @@ -0,0 +1,73 @@ +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, chars) => { + read_value!($next, String).chars().collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +fn rec(i: usize, j: usize, k: i32, s: &mut [Vec]) -> i32 { + let h = s.len(); + let w = s[0].len(); + if s[i][j] != '.' { + return 0; + } + if k == 0 { + return 1; + } + s[i][j] = 'x'; + let mut ret = 0; + for d in 0..4 { + let ni = i as i64 + [0, 1, 0, -1][d]; + let nj = j as i64 + [1, 0, -1, 0][d]; + if ni >= 0 && ni < h as i64 && nj >= 0 && nj < w as i64 { + ret += rec(ni as usize, nj as usize, k - 1, s); + } + } + s[i][j] = '.'; + ret +} + +fn main() { + input! { + h: usize, w: usize, k: i32, + s: [chars; h], + } + let mut s = s; + let mut ans = 0; + for i in 0..h { + for j in 0..w { + if s[i][j] == '#' { + continue; + } + ans += rec(i, j, k, &mut s); + } + } + println!("{}", ans) +} diff --git a/atcoder/abc378/e.rs b/atcoder/abc378/e.rs new file mode 100644 index 00000000..fa426db6 --- /dev/null +++ b/atcoder/abc378/e.rs @@ -0,0 +1,108 @@ +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +// Segment Tree. This data structure is useful for fast folding on intervals of an array +// whose elements are elements of monoid I. Note that constructing this tree requires the identity +// element of I and the operation of I. +// Verified by: yukicoder No. 2220 (https://yukicoder.me/submissions/841554) +struct SegTree { + n: usize, + orign: usize, + dat: Vec, + op: BiOp, + e: I, +} + +impl SegTree + where BiOp: Fn(I, I) -> I, + I: Copy { + pub fn new(n_: usize, op: BiOp, e: I) -> Self { + let mut n = 1; + while n < n_ { n *= 2; } // n is a power of 2 + SegTree {n: n, orign: n_, dat: vec![e; 2 * n - 1], op: op, e: e} + } + // ary[k] <- v + pub fn update(&mut self, idx: usize, v: I) { + debug_assert!(idx < self.orign); + let mut k = idx + self.n - 1; + self.dat[k] = v; + while k > 0 { + k = (k - 1) / 2; + self.dat[k] = (self.op)(self.dat[2 * k + 1], self.dat[2 * k + 2]); + } + } + // [a, b) (half-inclusive) + // http://proc-cpuinfo.fixstars.com/2017/07/optimize-segment-tree/ + #[allow(unused)] + pub fn query(&self, rng: std::ops::Range) -> I { + let (mut a, mut b) = (rng.start, rng.end); + debug_assert!(a <= b); + debug_assert!(b <= self.orign); + let mut left = self.e; + let mut right = self.e; + a += self.n - 1; + b += self.n - 1; + while a < b { + if (a & 1) == 0 { + left = (self.op)(left, self.dat[a]); + } + if (b & 1) == 0 { + right = (self.op)(self.dat[b - 1], right); + } + a = a / 2; + b = (b - 1) / 2; + } + (self.op)(left, right) + } +} + +fn main() { + input! { + n: usize, m: usize, + a: [usize; n], + } + let mut acc = vec![0; n + 1]; + for i in 0..n { + acc[i + 1] = (acc[i] + a[i]) % m; + } + let mut st = SegTree::new(m, |x, y| x + y, 0i64); + let mut mcount = 0; + for i in 0..n + 1 { + mcount += st.query(acc[i] + 1..m); + let val = st.query(acc[i]..acc[i] + 1); + st.update(acc[i], val + 1); + } + let mut ans = m as i64 * mcount; + for i in 0..n + 1 { + ans += acc[i] as i64 * (2 * i as i64 - n as i64); + } + println!("{}", ans); +} diff --git a/atcoder/abc378/f.rs b/atcoder/abc378/f.rs new file mode 100644 index 00000000..70e1f268 --- /dev/null +++ b/atcoder/abc378/f.rs @@ -0,0 +1,149 @@ +// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 +macro_rules! input { + ($($r:tt)*) => { + let stdin = std::io::stdin(); + let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock())); + let mut next = move || -> String{ + bytes.by_ref().map(|r|r.unwrap() as char) + .skip_while(|c|c.is_whitespace()) + .take_while(|c|!c.is_whitespace()) + .collect() + }; + input_inner!{next, $($r)*} + }; +} + +macro_rules! input_inner { + ($next:expr) => {}; + ($next:expr,) => {}; + ($next:expr, $var:ident : $t:tt $($r:tt)*) => { + let $var = read_value!($next, $t); + input_inner!{$next $($r)*} + }; +} + +macro_rules! read_value { + ($next:expr, ( $($t:tt),* )) => { ($(read_value!($next, $t)),*) }; + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, usize1) => (read_value!($next, usize) - 1); + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +// Union-Find tree. +// Verified by https://atcoder.jp/contests/pakencamp-2019-day3/submissions/9253305 +struct UnionFind { disj: Vec, rank: Vec } + +impl UnionFind { + fn new(n: usize) -> Self { + let disj = (0..n).collect(); + UnionFind { disj: disj, rank: vec![1; n] } + } + fn root(&mut self, x: usize) -> usize { + if x != self.disj[x] { + let par = self.disj[x]; + let r = self.root(par); + self.disj[x] = r; + } + self.disj[x] + } + fn unite(&mut self, x: usize, y: usize) { + let mut x = self.root(x); + let mut y = self.root(y); + if x == y { return } + if self.rank[x] > self.rank[y] { + std::mem::swap(&mut x, &mut y); + } + self.disj[x] = y; + self.rank[y] += self.rank[x]; + } + #[allow(unused)] + fn is_same_set(&mut self, x: usize, y: usize) -> bool { + self.root(x) == self.root(y) + } + #[allow(unused)] + fn size(&mut self, x: usize) -> usize { + let x = self.root(x); + self.rank[x] + } +} + +fn main() { + // In order to avoid potential stack overflow, spawn a new thread. + let stack_size = 104_857_600; // 100 MB + let thd = std::thread::Builder::new().stack_size(stack_size); + thd.spawn(|| solve()).unwrap().join().unwrap(); +} + +fn solve() { + input! { + n: usize, + uv: [(usize1, usize1); n - 1], + } + let mut g = vec![vec![]; n]; + for &(u, v) in &uv { + g[u].push(v); + g[v].push(u); + } + let mut ex2 = vec![]; + let mut exindex = vec![n * 2; n]; + for i in 0..n { + if g[i].len() == 2 { + exindex[i] = ex2.len(); + ex2.push(i); + } + } + let ext_idx = |v: usize, to: usize| -> usize { + assert_eq!(g[v].len(), 2); + let u = g[v][0]; + if u == to { + return v; + } + assert_eq!(g[v][1], to); + n + exindex[v] + }; + let mut uf = UnionFind::new(n + ex2.len()); + for i in 0..n { + if g[i].len() != 2 && g[i].len() != 3 { + continue; + } + if g[i].len() == 3 { + for &w in &g[i] { + if g[w].len() == 3 { + uf.unite(i, w); + } + } + continue; + } + assert_eq!(g[i].len(), 2); + let u = g[i][0]; + let v = g[i][1]; + let mut con = |x: usize, y: usize| { + assert_eq!(g[x].len(), 2); + let xidx = ext_idx(x, y); + if g[y].len() == 3 { + uf.unite(xidx, y); + return; + } + if g[y].len() != 2 { + return; + } + return; + }; + con(i, u); + con(i, v); + } + let mut twos = vec![0i64; n + ex2.len()]; + for i in 0..n + ex2.len() { + let ok = if i < n { g[i].len() == 2 } else { true }; + if ok { + twos[uf.root(i)] += 1; + } + } + let mut ans = 0i64; + for v in twos { + ans += v * (v - 1) / 2; + } + println!("{}", ans); +} diff --git a/atcoder/abc378/remain.txt b/atcoder/abc378/remain.txt new file mode 100644 index 00000000..01058d84 --- /dev/null +++ b/atcoder/abc378/remain.txt @@ -0,0 +1 @@ +g