結果
問題 | No.2470 Gemini Tree(Ver.Jadeite) |
ユーザー |
![]() |
提出日時 | 2023-08-17 18:39:18 |
言語 | Rust (1.83.0 + proconio) |
結果 |
AC
|
実行時間 | 348 ms / 5,000 ms |
コード長 | 18,564 bytes |
コンパイル時間 | 13,733 ms |
コンパイル使用メモリ | 376,088 KB |
実行使用メモリ | 34,504 KB |
最終ジャッジ日時 | 2024-11-26 17:49:44 |
合計ジャッジ時間 | 24,252 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 27 |
コンパイルメッセージ
warning: unused variable: `c` --> src/main.rs:36:17 | 36 | for &(a, b, c) in e.iter() { | ^ help: if this is intentional, prefix it with an underscore: `_c` | = note: `#[warn(unused_variables)]` on by default warning: unused variable: `a` --> src/main.rs:126:14 | 126 | let (a, b, w) = e[i]; | ^ help: if this is intentional, prefix it with an underscore: `_a` warning: unused variable: `b` --> src/main.rs:126:17 | 126 | let (a, b, w) = e[i]; | ^ help: if this is intentional, prefix it with an underscore: `_b` warning: unused variable: `src` --> src/main.rs:41:17 | 41 | let topo = |src: usize| -> Vec<(usize, usize)> { | ^^^ help: if this is intentional, prefix it with an underscore: `_src` warning: unused variable: `p` --> src/main.rs:109:14 | 109 | let (p, c) = if hld.parent[a] == b { (b, a) } else { (a, b) }; | ^ help: if this is intentional, prefix it with an underscore: `_p` warning: variable does not need to be mutable --> src/main.rs:112:13 | 112 | let mut y = pos.lower_bound(&r); | ----^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default warning: variable does not need to be mutable --> src/main.rs:102:9 | 102 | let mut seg = std::cell::RefCell::new(LazySegmentTree::build( | ----^^^ | | | help: remove this `mut` warning: type alias `Map` is never used --> src/main.rs:4:6 | 4 | type Map<K, V> = BTreeMap<K, V>; | ^^^ | = note: `#[warn(dead_code)]` on by default warning: type alias `Set` is never used --> src/main.rs:5:6 | 5 | type Set<T> = BTreeSet<T>; | ^^^ warning: type alias `Deque` is never used --> src/main.rs:6:6 | 6 | type Deque<T> = VecDeque<T>; | ^^^^^
ソースコード
use std::collections::*;use std::io::Write;type Map<K, V> = BTreeMap<K, V>;type Set<T> = BTreeSet<T>;type Deque<T> = VecDeque<T>;fn run() {input! {n: usize,s: bytes,e: [(usize1, usize1, i64); n - 1],q: usize,ask: [(usize1, i64); q],}let mut s = s;let mut cnt = [0; 2];for s in s.iter_mut() {if *s == b'G' {*s = 0;} else {*s = 1;}cnt[*s as usize] += 1;}let out = std::io::stdout();let mut out = std::io::BufWriter::new(out.lock());if cnt[0].max(cnt[1]) == n {for _ in 0..q {writeln!(out, "0").ok();}return;}let mut g = vec![vec![]; n];let mut hld = HLD::new(n);for &(a, b, c) in e.iter() {g[a].push(b);g[b].push(a);hld.add_edge(a, b);}let topo = |src: usize| -> Vec<(usize, usize)> {let mut res = vec![(0, n)];for i in 0..n {let (v, p) = res[i];for &u in g[v].iter() {if u != p {res.push((u, v));}}}res};let ord = topo(0);let mut root = 0;let mut size = vec![1; n];for &(v, p) in ord.iter().rev() {let mut max = 0usize;for &u in g[v].iter() {if u != p {max = max.max(size[u]);size[v] += size[u];}}max = max.max(n - size[v]);if 2 * max <= n {root = v;break;}}hld.build(root);let mut dp = s.iter().map(|s| {let mut cnt = [0; 2];cnt[*s as usize] += 1;cnt}).collect::<Vec<_>>();for i in (0..n).rev() {let v = hld.vertex(i);let mut val = dp[v];for &u in hld.child[v].iter() {val[0] += dp[u][0];val[1] += dp[u][1];}dp[v] = val;}if cnt[0] > cnt[1] {for dp in dp.iter_mut() {*dp = [dp[1], dp[0]];}cnt = [cnt[1], cnt[0]];}let mut pos = vec![];for i in 0..n {let v = hld.vertex(i);let (l, r) = hld.sub_tree(v);if r - l == cnt[0] {pos.push(i);}}let mut seg = std::cell::RefCell::new(LazySegmentTree::build((0..pos.len()).map(|_| 0),pos.len(),R,));let update = |k: usize, w: i64| {let (a, b, _) = e[k];let (p, c) = if hld.parent[a] == b { (b, a) } else { (a, b) };let (l, r) = hld.sub_tree(c);let mut x = pos.lower_bound(&l);let mut y = pos.lower_bound(&r);let sub = dp[c];let mut seg = seg.borrow_mut();if x > 0 && hld.sub_tree(hld.vertex(pos[x - 1])).1 >= r {seg.update(x - 1, x, w * sub[1] as i64);x -= 1;} else {let need = cnt[0] - sub[0];seg.update(x, y, w * need as i64);}seg.update(0, x, w * sub[0] as i64);seg.update(y, pos.len(), w * sub[0] as i64);};for i in 0..(n - 1) {let (a, b, w) = e[i];update(i, w);// writeln!(out, "{}", seg.borrow_mut().find(0, pos.len())).ok();}for (k, w) in ask {update(k, w);writeln!(out, "{}", seg.borrow_mut().find(0, pos.len())).ok();}}struct R;impl TE for R {type T = i64;type E = i64;fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T {std::cmp::min(*l, *r)}fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T {*x + *f}fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E {*g + *h}fn e(&self) -> Self::T {std::i64::MAX / 2}fn id(&self) -> Self::E {0}}fn main() {run();}// ---------- begin input macro ----------// reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8#[macro_export]macro_rules! input {(source = $s:expr, $($r:tt)*) => {let mut iter = $s.split_whitespace();input_inner!{iter, $($r)*}};($($r:tt)*) => {let s = {use std::io::Read;let mut s = String::new();std::io::stdin().read_to_string(&mut s).unwrap();s};let mut iter = s.split_whitespace();input_inner!{iter, $($r)*}};}#[macro_export]macro_rules! input_inner {($iter:expr) => {};($iter:expr, ) => {};($iter:expr, $var:ident : $t:tt $($r:tt)*) => {let $var = read_value!($iter, $t);input_inner!{$iter $($r)*}};}#[macro_export]macro_rules! read_value {($iter:expr, ( $($t:tt),* )) => {( $(read_value!($iter, $t)),* )};($iter:expr, [ $t:tt ; $len:expr ]) => {(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()};($iter:expr, chars) => {read_value!($iter, String).chars().collect::<Vec<char>>()};($iter:expr, bytes) => {read_value!($iter, String).bytes().collect::<Vec<u8>>()};($iter:expr, usize1) => {read_value!($iter, usize) - 1};($iter:expr, $t:ty) => {$iter.next().unwrap().parse::<$t>().expect("Parse error")};}// ---------- end input macro ----------// ---------- begin Heavy-Light decomposition ----------pub struct HLD {size: usize,edge: Vec<(usize, usize)>,child: Vec<Vec<usize>>,path_root: Vec<usize>,parent: Vec<usize>,left: Vec<usize>,right: Vec<usize>,inverse: Vec<usize>,}impl HLD {pub fn new(size: usize) -> Self {assert!(size <= 10usize.pow(8));HLD {size: size,edge: Vec::with_capacity(size - 1),child: Vec::new(),path_root: Vec::new(),parent: Vec::new(),left: Vec::new(),right: Vec::new(),inverse: Vec::new(),}}pub fn add_edge(&mut self, a: usize, b: usize) {assert!(a != b && a < self.size && b < self.size);self.edge.push((a, b));}pub fn build(&mut self, root: usize) {assert!(self.edge.len() + 1 == self.size);let size = self.size;let mut cnt = vec![0; size];for &(a, b) in self.edge.iter() {cnt[a] += 1;cnt[b] += 1;}let mut child = cnt.into_iter().map(|c| Vec::with_capacity(c)).collect::<Vec<_>>();for &(a, b) in self.edge.iter() {child[a].push(b);child[b].push(a);}let mut parent = vec![size; size];let mut q = Vec::with_capacity(size);q.push(root);parent[root] = root;for i in 0..size {let v = q[i];for u in child[v].clone() {assert!(parent[u] == size);parent[u] = v;child[u].retain(|e| *e != v);q.push(u);}}let mut sum = vec![1; size];for &v in q.iter().rev() {let child = &mut child[v];if !child.is_empty() {let (pos, _) = child.iter().enumerate().max_by_key(|p| sum[*p.1]).unwrap();child.swap(0, pos);sum[v] = 1 + child.iter().fold(0, |s, a| s + sum[*a]);}}let mut path_root = (0..size).collect::<Vec<_>>();let mut left = vec![0; size];let mut right = vec![0; size];let mut dfs = vec![(root, false)];let mut id = 0;while let Some((v, end)) = dfs.pop() {if end {right[v] = id;continue;}left[v] = id;id += 1;dfs.push((v, true));let child = &child[v];if !child.is_empty() {for &u in child[1..].iter() {path_root[u] = u;dfs.push((u, false));}let u = child[0];path_root[u] = path_root[v];dfs.push((u, false));}}let mut inverse = vec![size; size];for (i, l) in left.iter().enumerate() {inverse[*l] = i;}self.child = child;self.parent = parent;self.left = left;self.right = right;self.path_root = path_root;self.inverse = inverse;}pub fn lca(&self, mut a: usize, mut b: usize) -> usize {assert!(a < self.size && b < self.size);let path = &self.path_root;let parent = &self.parent;let index = &self.left;while path[a] != path[b] {if index[a] > index[b] {std::mem::swap(&mut a, &mut b);}b = parent[path[b]];}std::cmp::min((index[a], a), (index[b], b)).1}pub fn path(&self,src: usize,dst: usize,up: &mut Vec<(usize, usize)>,down: &mut Vec<(usize, usize)>,) {assert!(src < self.size && dst < self.size);up.clear();down.clear();let path = &self.path_root;let parent = &self.parent;let index = &self.left;let mut x = src;let mut y = dst;while path[x] != path[y] {if index[x] > index[y] {let p = path[x];assert!(p == path[p]);up.push((index[p], index[x] + 1));x = parent[p];} else {let p = path[y];assert!(p == path[p]);down.push((index[p], index[y] + 1));y = parent[p];}}if index[x] <= index[y] {down.push((index[x], index[y] + 1));} else {up.push((index[y], index[x] + 1));}down.reverse();}pub fn sub_tree(&self, v: usize) -> (usize, usize) {assert!(v < self.size);(self.left[v], self.right[v])}pub fn parent(&self, v: usize) -> Option<usize> {assert!(v < self.size);let p = self.parent[v];if p == v {None} else {Some(p)}}// s -> t へのパスの2番目の頂点を返すpub fn next(&self, s: usize, t: usize) -> usize {assert!(s < self.size && t < self.size && s != t);let (a, b) = self.sub_tree(s);let (c, d) = self.sub_tree(t);if !(a <= c && d <= b) {return self.parent[s];}let mut pos = t;let mut pre = t;while self.path_root[s] != self.path_root[pos] {pre = self.path_root[pos];pos = self.parent[pre];}if s == pos {pre} else {self.child[s][0]}}pub fn vertex(&self, x: usize) -> usize {assert!(x < self.size);self.inverse[x]}pub fn jump(&self,s: usize,t: usize,mut k: usize,up: &mut Vec<(usize, usize)>,down: &mut Vec<(usize, usize)>,) -> Option<usize> {assert!(s.max(t) < self.size);self.path(s, t, up, down);for (l, r) in up.drain(..) {if k < r - l {return Some(self.vertex(r - 1 - k));}k -= r - l;}for (l, r) in down.drain(..) {if k < r - l {return Some(self.vertex(l + k));}k -= r - l;}None}}// ---------- end Heavy-Light decomposition ----------// ---------- begin Lazy Segment Tree ----------pub trait TE {type T: Clone;type E: Clone;fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T;fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T;fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E;fn e(&self) -> Self::T;fn id(&self) -> Self::E;}pub struct LazySegmentTree<R: TE> {n: usize,size: usize,bit: u32,op: R,data: Vec<(R::T, R::E)>,}impl<R: TE> LazySegmentTree<R> {pub fn new(n: usize, op: R) -> Self {assert!(n > 0);let size = n.next_power_of_two();let bit = size.trailing_zeros();let data = vec![(op.e(), op.id()); 2 * size];Self {n,size,bit,op,data,}}pub fn build<I>(init: I, n: usize, op: R) -> SelfwhereI: Iterator<Item = R::T>,{let mut seg = Self::new(n, op);for (data, ini) in seg.data[seg.size..].iter_mut().zip(init) {data.0 = ini;}for i in (1..seg.size).rev() {seg.pull(i);}seg}pub fn update(&mut self, l: usize, r: usize, f: R::E) {assert!(l <= r && r <= self.n);if l == r {return;}self.push_range(l, r);let mut s = l + self.size;let mut t = r + self.size;while s < t {if s & 1 == 1 {self.apply(s, &f);s += 1;}if t & 1 == 1 {t -= 1;self.apply(t, &f);}s >>= 1;t >>= 1;}let l = l + self.size;let r = r + self.size;for k in 1..=self.bit {if (l >> k) << k != l {self.pull(l >> k);}if (r >> k) << k != r {self.pull((r - 1) >> k);}}}pub fn find(&mut self, l: usize, r: usize) -> R::T {assert!(l <= r && r <= self.n);if l == r {return self.op.e();}self.push_range(l, r);let mut l = l + self.size;let mut r = r + self.size;let mut p = self.op.e();let mut q = self.op.e();while l < r {if l & 1 == 1 {p = self.op.fold(&p, &self.data[l].0);l += 1;}if r & 1 == 1 {r -= 1;q = self.op.fold(&self.data[r].0, &q);}l >>= 1;r >>= 1;}self.op.fold(&p, &q)}pub fn set_at(&mut self, x: usize, v: R::T) {assert!(x < self.n);let x = x + self.size;for k in (1..=self.bit).rev() {self.push(x >> k);}self.data[x].0 = v;for k in 1..=self.bit {self.pull(x >> k);}}fn push_range(&mut self, l: usize, r: usize) {let l = l + self.size;let r = r + self.size;for k in (1..=self.bit).rev() {if (l >> k) << k != l {self.push(l >> k);}if (r >> k) << k != r {self.push((r - 1) >> k);}}}fn apply(&mut self, x: usize, f: &R::E) {self.data[x].0 = self.op.eval(&self.data[x].0, f);self.data[x].1 = self.op.merge(&self.data[x].1, f);}fn push(&mut self, x: usize) {let f = std::mem::replace(&mut self.data[x].1, self.op.id());self.apply(2 * x, &f);self.apply(2 * x + 1, &f);}fn pull(&mut self, x: usize) {self.data[x].0 = self.op.fold(&self.data[2 * x].0, &self.data[2 * x + 1].0);}}// ---------- end Lazy Segment Tree ----------// ---------- begin super slice ----------pub trait SuperSlice {type Item;fn lower_bound(&self, key: &Self::Item) -> usizewhereSelf::Item: Ord;fn lower_bound_by<F>(&self, f: F) -> usizewhereF: FnMut(&Self::Item) -> std::cmp::Ordering;fn lower_bound_by_key<K, F>(&self, key: &K, f: F) -> usizewhereK: Ord,F: FnMut(&Self::Item) -> K;fn upper_bound(&self, key: &Self::Item) -> usizewhereSelf::Item: Ord;fn upper_bound_by<F>(&self, f: F) -> usizewhereF: FnMut(&Self::Item) -> std::cmp::Ordering;fn upper_bound_by_key<K, F>(&self, key: &K, f: F) -> usizewhereK: Ord,F: FnMut(&Self::Item) -> K;fn next_permutation(&mut self) -> boolwhereSelf::Item: Ord;fn next_permutation_by<F>(&mut self, f: F) -> boolwhereF: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering;fn prev_permutation(&mut self) -> boolwhereSelf::Item: Ord;}impl<T> SuperSlice for [T] {type Item = T;fn lower_bound(&self, key: &Self::Item) -> usizewhereT: Ord,{self.lower_bound_by(|p| p.cmp(key))}fn lower_bound_by<F>(&self, mut f: F) -> usizewhereF: FnMut(&Self::Item) -> std::cmp::Ordering,{self.binary_search_by(|p| f(p).then(std::cmp::Ordering::Greater)).unwrap_err()}fn lower_bound_by_key<K, F>(&self, key: &K, mut f: F) -> usizewhereK: Ord,F: FnMut(&Self::Item) -> K,{self.lower_bound_by(|p| f(p).cmp(key))}fn upper_bound(&self, key: &Self::Item) -> usizewhereT: Ord,{self.upper_bound_by(|p| p.cmp(key))}fn upper_bound_by<F>(&self, mut f: F) -> usizewhereF: FnMut(&Self::Item) -> std::cmp::Ordering,{self.binary_search_by(|p| f(p).then(std::cmp::Ordering::Less)).unwrap_err()}fn upper_bound_by_key<K, F>(&self, key: &K, mut f: F) -> usizewhereK: Ord,F: FnMut(&Self::Item) -> K,{self.upper_bound_by(|p| f(p).cmp(key))}fn next_permutation(&mut self) -> boolwhereT: Ord,{self.next_permutation_by(|a, b| a.cmp(b))}fn next_permutation_by<F>(&mut self, mut f: F) -> boolwhereF: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,{use std::cmp::Ordering::*;if let Some(x) = self.windows(2).rposition(|a| f(&a[0], &a[1]) == Less) {let y = self.iter().rposition(|b| f(&self[x], b) == Less).unwrap();self.swap(x, y);self[(x + 1)..].reverse();true} else {self.reverse();false}}fn prev_permutation(&mut self) -> boolwhereT: Ord,{self.next_permutation_by(|a, b| a.cmp(b).reverse())}}// ---------- end super slice ----------