提出 #44445673


ソースコード 拡げる

use proconio::{input, marker::Usize1};

fn dfs(
    depth: &mut Vec<usize>,
    parent: &mut Vec<usize>,
    edges: &[Vec<usize>],
    u: usize,
    p: usize,
    d: usize,
) {
    depth[u] = d;
    parent[u] = p;
    for v in edges[u].iter().copied() {
        if v == p {
            continue;
        }
        dfs(depth, parent, edges, v, u, d + 1);
    }
}

fn parent_doubling(p: &[usize]) -> Vec<Vec<usize>> {
    let n = p.len();
    let k_len = p.len().next_power_of_two().trailing_zeros() as usize;
    let mut res = vec![vec![n; n]; k_len];
    for (i, p_i) in p.iter().copied().enumerate() {
        res[0][i] = p_i;
    }
    for k in 0..k_len - 1 {
        for i in 0..p.len() {
            if res[k][i] == n {
                res[k + 1][i] = n;
            } else {
                res[k + 1][i] = res[k][res[k][i]];
            }
        }
    }
    res
}

fn lca_by_doubling(depth: &[usize], parent: &[Vec<usize>], u: usize, v: usize) -> usize {
    let k_len = parent.len();
    let (mut u, mut v) = if depth[u] < depth[v] { (u, v) } else { (v, u) };
    for k in 0..k_len {
        if (((depth[v] - depth[u]) >> k) & 1) == 1 {
            v = parent[k][v];
        }
    }
    if u == v {
        return u;
    }
    for k in (0..k_len).rev() {
        if parent[k][u] != parent[k][v] {
            u = parent[k][u];
            v = parent[k][v];
        }
    }
    assert_eq!(parent[0][u], parent[0][v]);
    parent[0][u]
}

fn get_leader(leader: &mut [usize], u: usize) -> usize {
    if leader[u] == u {
        u
    } else {
        leader[u] = get_leader(leader, leader[u]);
        leader[u]
    }
}

fn merge(leader: &mut [usize], depth: &[usize], u: usize, v: usize) {
    let (mut x, mut y) = (get_leader(leader, u), get_leader(leader, v));
    if x == y {
        return;
    }
    if depth[x] > depth[y] {
        std::mem::swap(&mut x, &mut y);
    }
    leader[y] = leader[x];
}

fn main() {
    input! {
        n: usize,
        q: usize,
        ab: [(Usize1, Usize1); n - 1],
        uvc: [(Usize1, Usize1, usize); q],
    }

    let mut edges = vec![vec![]; n];
    for (a, b) in ab.iter().copied() {
        edges[a].push(b);
        edges[b].push(a);
    }

    let (depth, parent1) = {
        let mut depth = vec![0; n];
        let mut parent1 = vec![0; n];
        dfs(&mut depth, &mut parent1, &edges, 0, 0, 0);
        (depth, parent1)
    };

    let mut index = vec![n; n];
    for (i, (a, b)) in ab.iter().copied().enumerate() {
        let child = if depth[a] < depth[b] { b } else { a };
        index[child] = i;
    }

    let parent = parent_doubling(&parent1);

    let mut color = vec![0; n];
    let mut leader = (0..n).collect::<Vec<usize>>();
    for (mut u, mut v, c) in uvc.into_iter().rev() {
        let lca = lca_by_doubling(&depth, &parent, u, v);

        // u -> lca
        u = get_leader(&mut leader, u);
        while depth[u] > depth[lca] {
            color[index[u]] = c;
            let p = parent1[u];
            merge(&mut leader, &depth, u, p);
            u = get_leader(&mut leader, p);
        }

        // v -> lca
        v = get_leader(&mut leader, v);
        while depth[v] > depth[lca] {
            color[index[v]] = c;
            let p = parent1[v];
            merge(&mut leader, &depth, v, p);
            v = get_leader(&mut leader, p);
        }
    }

    for i in 0..n - 1 {
        println!("{}", color[i]);
    }
}

提出情報

提出日時
問題 M - 筆塗り
ユーザ bouzuya
言語 Rust (1.42.0)
得点 6
コード長 3414 Byte
結果 AC
実行時間 288 ms
メモリ 36580 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 6 / 6
結果
AC × 2
AC × 32
セット名 テストケース
Sample sample_01.txt, sample_02.txt
All random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, random_15.txt, random_16.txt, random_17.txt, random_18.txt, random_19.txt, random_20.txt, random_21.txt, random_22.txt, random_23.txt, random_24.txt, random_25.txt, random_26.txt, random_27.txt, random_28.txt, random_29.txt, random_30.txt, sample_01.txt, sample_02.txt
ケース名 結果 実行時間 メモリ
random_01.txt AC 7 ms 2084 KiB
random_02.txt AC 282 ms 31852 KiB
random_03.txt AC 193 ms 26168 KiB
random_04.txt AC 31 ms 4148 KiB
random_05.txt AC 121 ms 16612 KiB
random_06.txt AC 26 ms 3816 KiB
random_07.txt AC 101 ms 11988 KiB
random_08.txt AC 100 ms 13212 KiB
random_09.txt AC 213 ms 27332 KiB
random_10.txt AC 126 ms 15096 KiB
random_11.txt AC 6 ms 2000 KiB
random_12.txt AC 288 ms 32460 KiB
random_13.txt AC 188 ms 26464 KiB
random_14.txt AC 215 ms 25612 KiB
random_15.txt AC 163 ms 19836 KiB
random_16.txt AC 148 ms 25244 KiB
random_17.txt AC 240 ms 36580 KiB
random_18.txt AC 86 ms 14452 KiB
random_19.txt AC 218 ms 32792 KiB
random_20.txt AC 41 ms 6148 KiB
random_21.txt AC 54 ms 8508 KiB
random_22.txt AC 50 ms 7456 KiB
random_23.txt AC 61 ms 8900 KiB
random_24.txt AC 88 ms 14008 KiB
random_25.txt AC 80 ms 10184 KiB
random_26.txt AC 80 ms 11928 KiB
random_27.txt AC 95 ms 11524 KiB
random_28.txt AC 185 ms 23740 KiB
random_29.txt AC 181 ms 26196 KiB
random_30.txt AC 162 ms 22184 KiB
sample_01.txt AC 2 ms 2140 KiB
sample_02.txt AC 3 ms 2176 KiB