結果

問題 No.399 動的な領主
ユーザー koba-e964
提出日時 2017-03-06 00:08:26
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 237 ms / 2,000 ms
コード長 4,361 bytes
コンパイル時間 14,934 ms
コンパイル使用メモリ 377,820 KB
実行使用メモリ 38,784 KB
最終ジャッジ日時 2024-06-23 06:07:36
合計ジャッジ時間 18,945 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 19
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::Read;
#[allow(dead_code)]
fn getline() -> String {
let mut ret = String::new();
std::io::stdin().read_line(&mut ret).ok().unwrap();
ret
}
fn get_word() -> String {
let mut stdin = std::io::stdin();
let mut u8b: [u8; 1] = [0];
loop {
let mut buf: Vec<u8> = Vec::with_capacity(16);
loop {
let res = stdin.read(&mut u8b);
if res.unwrap_or(0) == 0 || u8b[0] <= b' ' {
break;
} else {
buf.push(u8b[0]);
}
}
if buf.len() >= 1 {
let ret = String::from_utf8(buf).unwrap();
return ret;
}
}
}
#[allow(dead_code)]
fn get<T: std::str::FromStr>() -> T { get_word().parse().ok().unwrap() }
/**
* Lowest Common Ancestor. Call lca(x, y) to get the lca of them.
* Verified by:
*/
pub struct LowestCommonAncestor {
n: usize,
bn: usize,
parent: Vec<usize>, // 0 is root, parent[0] = 0
dep: Vec<usize>,
lca_tbl: Vec<Vec<usize>>
}
impl LowestCommonAncestor {
fn dfs(&mut self, edges: &[Vec<usize>], v: usize, par: usize, d: usize) {
self.parent[v] = par;
self.dep[v] = d;
for &u in edges[v].iter() {
if u != par {
self.dfs(edges, u, v, d + 1);
}
}
}
fn lca_init(&mut self) {
let n = self.n;
for v in 0 .. n {
self.lca_tbl[v] = vec![0; self.bn + 1];
self.lca_tbl[v][0] = self.parent[v];
}
for i in 1 .. self.bn + 1 {
for v in 0 .. n {
self.lca_tbl[v][i] =
self.lca_tbl[self.lca_tbl[v][i - 1]][i - 1];
}
}
}
pub fn lca(&self, mut x: usize, mut y: usize) -> usize {
let dx = self.dep[x];
let mut dy = self.dep[y];
if dx > dy {
return self.lca(y, x);
}
for l in (0 .. self.bn + 1).rev() {
if dy - dx >= 1 << l {
y = self.lca_tbl[y][l];
dy -= 1 << l;
}
}
assert_eq!(dx, dy);
if x == y {
return x;
}
for l in (0 .. self.bn + 1).rev() {
if self.lca_tbl[x][l] != self.lca_tbl[y][l] {
x = self.lca_tbl[x][l];
y = self.lca_tbl[y][l];
}
}
self.lca_tbl[x][0]
}
#[allow(unused)]
pub fn depth(&self, a: usize) -> usize {
self.dep[a]
}
pub fn parent(&self, a: usize) -> usize {
self.parent[a]
}
pub fn new(edges: &[Vec<usize>]) -> Self {
let n = edges.len();
let bn = (n.next_power_of_two() - 1).count_ones() as usize;
let mut ret = LowestCommonAncestor {
n: n, bn: bn, parent: vec![0; n], dep: vec![0; n],
lca_tbl: vec![Vec::new(); n] };
ret.dfs(edges, 0, 0, 0);
ret.lca_init();
ret
}
}
fn dfs(v: usize, par: Option<usize>, edges: &[Vec<usize>], dp: &mut [i64]) {
let mut tot = 0;
for &w in edges[v].iter() {
if Some(w) == par { continue; }
dfs(w, Some(v), edges, dp);
let child = dp[w];
tot += child;
}
dp[v] += tot;
}
fn solve() {
let n = get();
let mut edges = vec![Vec::new(); n];
for _ in 0 .. n - 1 {
let u: usize = get::<usize>() - 1;
let v: usize = get::<usize>() - 1;
edges[u].push(v);
edges[v].push(u);
}
let lca = LowestCommonAncestor::new(&edges);
let q = get();
let mut dp = vec![0; n];
for _ in 0 .. q {
let a: usize = get::<usize>() - 1;
let b: usize = get::<usize>() - 1;
let anc = lca.lca(a, b);
dp[a] += 1;
dp[b] += 1;
dp[anc] -= 1;
if anc != lca.parent(anc) {
dp[lca.parent(anc)] -= 1;
}
}
// Recover full trace (imos)
dfs(0, None, &edges, &mut dp);
let mut tot = 0;
for ent in dp {
tot += ent * (ent + 1) / 2;
}
println!("{}", tot);
}
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();
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0