haar_lib/ds/
partially_persistent_unionfind.rs1pub struct PartiallyPersistentUnionFind {
9 time: usize,
10 p: Vec<Vec<(usize, usize)>>,
11 par: Vec<usize>,
12 rank: Vec<usize>,
13}
14
15pub struct At<'a> {
17 time: usize,
18 p: &'a Vec<Vec<(usize, usize)>>,
19 par: &'a Vec<usize>,
20}
21
22impl PartiallyPersistentUnionFind {
23 pub fn new(size: usize) -> Self {
25 Self {
26 time: 0,
27 p: vec![vec![(0, 1)]; size],
28 par: (0..size).collect(),
29 rank: vec![1; size],
30 }
31 }
32
33 pub fn at(&self, t: usize) -> At {
35 assert!(t <= self.time);
36 At {
37 time: t,
38 p: &self.p,
39 par: &self.par,
40 }
41 }
42
43 pub fn latest(&self) -> At {
45 self.at(self.time)
46 }
47
48 pub fn merge(&mut self, u: usize, v: usize) {
50 let t = self.time;
51 self.time += 1;
52
53 let u = self.at(t).root_of(u);
54 let v = self.at(t).root_of(v);
55
56 if u == v {
57 return;
58 }
59
60 let s = self.p[u].last().unwrap().1 + self.p[v].last().unwrap().1;
61
62 if self.rank[u] < self.rank[v] {
63 self.par[u] = v;
64 self.par[v] = v;
65 self.p[u].push((self.time, v));
66 self.p[v].push((self.time, s));
67 } else {
68 self.par[u] = u;
69 self.par[v] = u;
70 self.p[v].push((self.time, u));
71 self.p[u].push((self.time, s));
72 if self.rank[u] == self.rank[v] {
73 self.rank[u] += 1;
74 }
75 }
76 }
77}
78
79impl At<'_> {
80 pub fn root_of(&self, i: usize) -> usize {
82 let &(t, r) = self.p[i].last().unwrap();
83
84 if self.par[i] == i || t == 0 || self.time < t {
85 i
86 } else if self.time == t {
87 r
88 } else {
89 self.root_of(self.par[i])
90 }
91 }
92
93 pub fn is_same(&self, u: usize, v: usize) -> bool {
95 self.root_of(u) == self.root_of(v)
96 }
97
98 pub fn size_of(&self, u: usize) -> usize {
102 let u = self.root_of(u);
103
104 match self.p[u].binary_search(&(self.time + 1, 0)) {
105 Ok(i) | Err(i) => self.p[u][i - 1].1,
106 }
107 }
108}