From b9d4a8a558624a6c2fba286926f3ac176598e856 Mon Sep 17 00:00:00 2001 From: koba-e964 <3303362+koba-e964@users.noreply.github.com> Date: Fri, 3 May 2024 20:46:11 +0900 Subject: [PATCH] Add atcoder/abc339/c.rs atcoder/abc339/e.rs atcoder/abc339/g.rs --- atcoder/abc339/c.rs | 44 ++++++++++++ atcoder/abc339/e.rs | 100 ++++++++++++++++++++++++++ atcoder/abc339/g.rs | 144 ++++++++++++++++++++++++++++++++++++++ atcoder/abc339/remain.txt | 3 - 4 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 atcoder/abc339/c.rs create mode 100644 atcoder/abc339/e.rs create mode 100644 atcoder/abc339/g.rs diff --git a/atcoder/abc339/c.rs b/atcoder/abc339/c.rs new file mode 100644 index 00000000..54f86edd --- /dev/null +++ b/atcoder/abc339/c.rs @@ -0,0 +1,44 @@ +// 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! { + n: usize, + a: [i64; n], + } + let mut delta = 0; + let mut mi = 0; + for a in a { + delta += a; + mi = mi.min(delta); + } + println!("{}", delta - mi); +} diff --git a/atcoder/abc339/e.rs b/atcoder/abc339/e.rs new file mode 100644 index 00000000..ce0db1d0 --- /dev/null +++ b/atcoder/abc339/e.rs @@ -0,0 +1,100 @@ +// 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, d: usize, + a: [usize; n], + } + const W: usize = 1 << 19; + let mut st = SegTree::new(W, |x, y| x.max(y), 0); + for a in a { + let mut ma = st.query(a.max(d) - d..(a + d + 1).min(W)); + ma += 1; + st.update(a, ma); + } + println!("{}", st.query(0..W)); +} diff --git a/atcoder/abc339/g.rs b/atcoder/abc339/g.rs new file mode 100644 index 00000000..1331bddd --- /dev/null +++ b/atcoder/abc339/g.rs @@ -0,0 +1,144 @@ +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),* )) => { ($(read_value!($next, $t)),*) }; + ($next:expr, [ $t:tt ; $len:expr ]) => { + (0..$len).map(|_| read_value!($next, $t)).collect::>() + }; + ($next:expr, $t:ty) => ($next().parse::<$t>().expect("Parse error")); +} + +trait Bisect { + fn lower_bound(&self, val: &T) -> usize; + fn upper_bound(&self, val: &T) -> usize; +} + +impl Bisect for [T] { + fn lower_bound(&self, val: &T) -> usize { + let mut pass = self.len() + 1; + let mut fail = 0; + while pass - fail > 1 { + let mid = (pass + fail) / 2; + if &self[mid - 1] >= val { + pass = mid; + } else { + fail = mid; + } + } + pass - 1 + } + fn upper_bound(&self, val: &T) -> usize { + let mut pass = self.len() + 1; + let mut fail = 0; + while pass - fail > 1 { + let mid = (pass + fail) / 2; + if &self[mid - 1] > val { + pass = mid; + } else { + fail = mid; + } + } + pass - 1 + } +} + +struct BIT2D { + n: i32, + m: i32, + dat: HashMap<(i32, i32), i64>, +} + +impl BIT2D { + pub fn new(n: i32, m: i32) -> Self { + BIT2D { + n: n, + m: m, + dat: HashMap::new(), + } + } + pub fn add(&mut self, x: i32, y: i32, val: i64) { + let mut x = x; + while x <= self.n { + let mut y = y; + while y <= self.m { + *self.dat.entry((x, y)).or_insert(0) += val; + y += y & -y; + } + x += x & -x; + } + } + pub fn sum(&self, mut xl: i32, mut xr: i32, y: i32) -> i64 { + let mut sum = 0; + let get = |x: i32| -> i64 { + let mut y = y; + let mut sum = 0; + while y > 0 { + sum += self.dat.get(&(x, y)).unwrap_or(&0); + y -= y & -y; + } + sum + }; + while xr != xl { + if xr > xl { + sum += get(xr); + xr -= xr & -xr; + } else { + sum -= get(xl); + xl -= xl & -xl; + } + } + sum + } +} + +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, + a: [i64; n], + q: usize, + abc: [(i64, i64, i64); q], + } + let mut occ = a.clone(); + occ.sort(); occ.dedup(); + let mut bit = BIT2D::new(n as i32, occ.len() as i32); + for i in 0..n { + let idx = occ.binary_search(&a[i]).unwrap(); + bit.add(i as i32 + 1, idx as i32 + 1, a[i]); + } + let mut g = 0; + for (a, b, c) in abc { + let l = (a ^ g) as i32; + let r = (b ^ g) as i32; + let x = c ^ g; + let idx = occ.upper_bound(&x) as i32; + g = bit.sum(l - 1, r, idx); + puts!("{}\n", g); + } +} diff --git a/atcoder/abc339/remain.txt b/atcoder/abc339/remain.txt index 9fbb6235..0969df20 100644 --- a/atcoder/abc339/remain.txt +++ b/atcoder/abc339/remain.txt @@ -1,6 +1,3 @@ b -c d -e f -g