QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#330106#8055. Balanceucup-team635#WA 0ms2148kbRust13.1kb2024-02-17 12:31:282024-02-17 12:31:29

Judging History

你现在查看的是最新测评结果

  • [2024-02-17 12:31:29]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:2148kb
  • [2024-02-17 12:31:28]
  • 提交

answer


// ---------- begin Rerooting ----------
pub trait RerootingOperator {
    type Value: Clone;
    type Edge: Clone;
    fn init(&mut self, v: usize) -> Self::Value;
    fn merge(&mut self, p: &Self::Value, c: &Self::Value, e: &Self::Edge) -> Self::Value;
}

pub struct Rerooting<R: RerootingOperator> {
    manager: R,
    size: usize,
    edge: Vec<(usize, usize, R::Edge, R::Edge)>,
}

impl<R: RerootingOperator> Rerooting<R> {
    pub fn new(size: usize, manager: R) -> Self {
        assert!(size > 0 && size < 10usize.pow(8));
        Rerooting {
            manager: manager,
            size: size,
            edge: vec![],
        }
    }
    pub fn add_edge(&mut self, a: usize, b: usize, cost: R::Edge) {
        assert!(a < self.size && b < self.size && a != b);
        self.add_edge_bi(a, b, cost.clone(), cost);
    }
    pub fn add_edge_bi(&mut self, a: usize, b: usize, ab: R::Edge, ba: R::Edge) {
        assert!(a < self.size && b < self.size && a != b);
        self.edge.push((a, b, ab, ba));
    }
    pub fn solve(&mut self) -> Vec<R::Value> {
        let size = self.size;
        let mut graph = vec![vec![]; size];
        for e in self.edge.iter() {
            graph[e.0].push((e.1, e.2.clone()));
            graph[e.1].push((e.0, e.3.clone()));
        }
        let root = 0;
        let mut topo = vec![root];
        let mut parent = vec![root; size];
        let mut parent_edge: Vec<Option<R::Edge>> = (0..size).map(|_| None).collect();
        for i in 0..size {
            let v = topo[i];
            let child = std::mem::take(&mut graph[v]);
            for e in child.iter() {
                let k = graph[e.0].iter().position(|e| e.0 == v).unwrap();
                let c = graph[e.0].remove(k).1;
                parent_edge[e.0] = Some(c);
                parent[e.0] = v;
                topo.push(e.0);
            }
            graph[v] = child;
        }
        let manager = &mut self.manager;
        let mut down: Vec<_> = (0..size).map(|v| manager.init(v)).collect();
        for &v in topo.iter().rev() {
            for e in graph[v].iter() {
                down[v] = manager.merge(&down[v], &down[e.0], &e.1);
            }
        }
        let mut up: Vec<_> = (0..size).map(|v| manager.init(v)).collect();
        let mut stack = vec![];
        for &v in topo.iter() {
            if let Some(e) = parent_edge[v].take() {
                let ini = manager.init(v);
                up[v] = manager.merge(&ini, &up[v], &e);
            }
            if !graph[v].is_empty() {
                stack.push((graph[v].as_slice(), up[v].clone()));
                while let Some((g, val)) = stack.pop() {
                    if g.len() == 1 {
                        up[g[0].0] = val;
                    } else {
                        let m = g.len() / 2;
                        let (a, b) = g.split_at(m);
                        for a in [(a, b), (b, a)].iter() {
                            let mut p = val.clone();
                            for a in a.0.iter() {
                                p = manager.merge(&p, &down[a.0], &a.1);
                            }
                            stack.push((a.1, p));
                        }
                    }
                }
            }
            for e in graph[v].iter() {
                up[v] = manager.merge(&up[v], &down[e.0], &e.1);
            }
        }
        up
    }
}
// ---------- end Rerooting ----------
mod util {
    pub trait Join {
        fn join(self, sep: &str) -> String;
    }

    impl<T, I> Join for I
    where
        I: Iterator<Item = T>,
        T: std::fmt::Display,
    {
        fn join(self, sep: &str) -> String {
            let mut s = String::new();
            use std::fmt::*;
            for (i, v) in self.enumerate() {
                if i > 0 {
                    write!(&mut s, "{}", sep).ok();
                }
                write!(&mut s, "{}", v).ok();
            }
            s
        }
    }
}
// ---------- begin chmin, chmax ----------
pub trait ChangeMinMax {
    fn chmin(&mut self, x: Self) -> bool;
    fn chmax(&mut self, x: Self) -> bool;
}

impl<T: PartialOrd> ChangeMinMax for T {
    fn chmin(&mut self, x: Self) -> bool {
        *self > x && {
            *self = x;
            true
        }
    }
    fn chmax(&mut self, x: Self) -> bool {
        *self < x && {
            *self = x;
            true
        }
    }
}
// ---------- end chmin, chmax ----------
// ---------- begin quick find ----------
pub struct QuickFind {
    size: usize,
    id: Vec<usize>,
    list: Vec<Vec<usize>>,
}

impl QuickFind {
    pub fn new(size: usize) -> Self {
        let id = (0..size).collect::<Vec<_>>();
        let list = (0..size).map(|x| vec![x]).collect::<Vec<_>>();
        QuickFind { size, id, list }
    }
    pub fn root(&self, x: usize) -> usize {
        assert!(x < self.size);
        self.id[x]
    }
    pub fn same(&self, x: usize, y: usize) -> bool {
        assert!(x < self.size);
        assert!(y < self.size);
        self.root(x) == self.root(y)
    }
    pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> {
        assert!(x < self.size);
        assert!(y < self.size);
        let mut x = self.root(x);
        let mut y = self.root(y);
        if x == y {
            return None;
        }
        if (self.list[x].len(), x) < (self.list[y].len(), y) {
            std::mem::swap(&mut x, &mut y);
        }
        let mut z = std::mem::take(&mut self.list[y]);
        z.iter().for_each(|y| self.id[*y] = x);
        self.list[x].append(&mut z);
        Some((x, y))
    }
    pub fn enumerate(&self, x: usize) -> &[usize] {
        assert!(x < self.size);
        &self.list[self.root(x)]
    }
    pub fn size(&self, x: usize) -> usize {
        assert!(x < self.size);
        self.enumerate(x).len()
    }
}
// ---------- end quick find ----------
// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
    use std::str::FromStr;
    pub struct Scanner<'a> {
        it: std::str::SplitWhitespace<'a>,
    }
    impl<'a> Scanner<'a> {
        pub fn new(s: &'a String) -> Scanner<'a> {
            Scanner {
                it: s.split_whitespace(),
            }
        }
        pub fn next<T: FromStr>(&mut self) -> T {
            self.it.next().unwrap().parse::<T>().ok().unwrap()
        }
        pub fn next_bytes(&mut self) -> Vec<u8> {
            self.it.next().unwrap().bytes().collect()
        }
        pub fn next_chars(&mut self) -> Vec<char> {
            self.it.next().unwrap().chars().collect()
        }
        pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
            (0..len).map(|_| self.next()).collect()
        }
    }
}
// ---------- end scannner ----------

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 main() {
    use std::io::Read;
    let mut s = String::new();
    std::io::stdin().read_to_string(&mut s).unwrap();
    let mut sc = scanner::Scanner::new(&s);
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    run(&mut sc, &mut out);
}

fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
    let t: u32 = sc.next();
    for _ in 0..t {
        let n: usize = sc.next();
        let m: usize = sc.next();
        let mut e = vec![(0, 0); m];
        let mut test = QuickFind::new(n);
        for e in e.iter_mut() {
            e.0 = sc.next::<usize>() - 1;
            e.1 = sc.next::<usize>() - 1;
            test.unite(e.0, e.1);
        }
        let a: Vec<usize> = sc.next_vec(n);
        if test.size(0) != n {
            writeln!(out, "No").ok();
            continue;
        }
        let mut g = vec![vec![]; n];
        for (i, &(a, b)) in e.iter().enumerate() {
            g[a].push((b, i));
            g[b].push((a, i));
        }
        let mut ord = vec![n; n];
        let mut low = vec![n; n];
        let mut id = 0;
        dfs(0, m, &g, &mut ord, &mut low, &mut id);
        let mut dsu = QuickFind::new(n);
        for (x, y) in ord.iter().zip(low.iter()) {
            dsu.unite(*x, *y);
        }
        drop(g);
        drop(ord);
        drop(low);
        let vertex = (0..n).filter(|v| *v == dsu.root(*v)).collect::<Vec<_>>();
        let mut tree = vec![vec![]; vertex.len()];
        let mut edge = vec![];
        for &(a, b) in e.iter() {
            if dsu.root(a) != dsu.root(b) {
                let a = vertex.binary_search(&dsu.root(a)).unwrap();
                let b = vertex.binary_search(&dsu.root(b)).unwrap();
                edge.push((a, b));
                tree[a].push(b);
                tree[b].push(a);
            }
        }
        let g = tree;
        let mut z = a.clone();
        z.sort();
        z.dedup();
        let z = z;
        let mut hist = vec![0; z.len() + 1];
        for a in a.iter() {
            let x = z.binary_search(a).unwrap();
            hist[x + 1] += 1;
        }
        for i in 1..hist.len() {
            hist[i] += hist[i - 1];
        }
        let hist = hist;
        let mut inv = vec![None; n + 1];
        for i in 1..hist.len() {
            inv[hist[i]] = Some(i);
        }
        let inv = inv;
        let size = vertex.iter().map(|v| dsu.size(*v)).collect::<Vec<_>>();
        let info = Info {
            inv: inv.clone(),
            size: size.clone(),
        };
        let mut solver = Rerooting::new(vertex.len(), info);
        for &(a, b) in edge.iter() {
            solver.add_edge(a, b, ());
        }
        let res = solver.solve();
        let v = (0..res.len()).find(|v| res[*v].1 == z.len() - 1);
        if v.is_none() {
            writeln!(out, "No").ok();
            continue;
        }
        let root = v.unwrap();
        let mut g = g;
        let mut topo = vec![root];
        for i in 0..g.len() {
            let v = topo[i];
            for u in g[v].clone() {
                g[u].retain(|p| *p != v);
                topo.push(u);
            }
        }
        let mut size = size;
        let mut dp = vec![0; g.len()];
        for &v in topo.iter().rev() {
            let mut val = 0;
            for &u in g[v].iter() {
                val.chmax(dp[u]);
                if let Some(k) = inv[size[u]] {
                    if dp[u] == k - 1 {
                        val.chmax(k);
                    }
                }
                size[v] += size[u];
            }
            dp[v] = val;
        }
        let mut del = Map::new();
        let mut pos = root;
        while dp[pos] > 0 {
            let mut update = false;
            for &u in g[pos].iter() {
                if dp[u] == dp[pos] {
                    pos = u;
                    update = true;
                    break;
                } else if inv[size[u]].map_or(false, |k| dp[u] == k - 1 && dp[pos] == k) {
                    del.insert((pos, u), dp[pos]);
                    pos = u;
                    update = true;
                    break;
                }
            }
            assert!(update);
        }
        let mut value = vec![z[0]; n];
        let mut add = vec![];
        for &(a, b) in edge.iter() {
            let mut update = false;
            if let Some(&v) = del.get(&(a, b)) {
                value[a] = z[v];
                update = true;
            }
            if let Some(&v) = del.get(&(b, a)) {
                value[b] = z[v];
                update = true;
            }
            if !update {
                add.push((a, b));
            }
        }
        for (a, b) in add {
            let (p, c) = dsu.unite(a, b).unwrap();
            if value[c] != z[0] {
                value[p] = value[c];
            }
        }
        writeln!(out, "Yes").ok();
        use util::*;
        writeln!(out, "{}", (0..n).map(|v| value[dsu.root(v)]).join(" ")).ok();
    }
}

fn dfs(
    v: usize,
    prev: usize,
    g: &[Vec<(usize, usize)>],
    ord: &mut [usize],
    low: &mut [usize],
    id: &mut usize,
) {
    ord[v] = *id;
    low[v] = *id;
    *id += 1;
    for &(u, k) in g[v].iter().filter(|e| e.1 != prev) {
        if ord[u] > *id {
            dfs(u, k, g, ord, low, id);
            low[v] = low[v].min(low[u]);
        } else {
            low[v] = low[v].min(ord[u]);
        }
    }
}

struct Info {
    inv: Vec<Option<usize>>,
    size: Vec<usize>,
}

impl RerootingOperator for Info {
    // size, value
    type Value = (usize, usize);
    type Edge = ();
    fn init(&mut self, v: usize) -> Self::Value {
        (self.size[v], 0)
    }
    fn merge(&mut self, p: &Self::Value, c: &Self::Value, e: &Self::Edge) -> Self::Value {
        let size = p.0 + c.0;
        let mut val = p.1.max(c.1);
        if let Some(k) = self.inv[c.0] {
            if c.1 == k - 1 {
                val = val.max(k);
            }
        }
        (size, val)
    }
}

详细

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 2148kb

input:

5
5 4
1 2
2 3
3 4
4 5
1 2 3 4 5
5 4
1 2
1 3
1 4
1 5
1 2 3 4 5
5 4
1 2
1 3
1 4
1 5
1 2 2 2 3
5 6
1 2
1 2
2 3
3 4
4 5
3 5
1 2 1 2 1
2 2
1 2
1 2
1 2

output:

Yes
5 4 3 2 1
No
Yes
2 3 1 2 2
Yes
1 1 1 1 1
No

result:

wrong answer 4-th smallest numbers are not same (test case 4)