Skip to content

Commit 58c443b

Browse files
committed
.
1 parent 9a94b58 commit 58c443b

6 files changed

+412
-0
lines changed

longest-common-subpath.cc

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#define FOR(i, a, b) for (remove_cv<remove_reference<decltype(b)>::type>::type i = (a); i < (b); i++)
2+
#define REP(i, n) FOR(i, 0, n)
3+
#define ROF(i, a, b) for (remove_cv<remove_reference<decltype(b)>::type>::type i = (b); --i >= (a); )
4+
5+
const long N = 200000;
6+
int a[N], pos[N], sa[N], r[N], h[N], x[N];
7+
8+
void suffix_array(int n, int m, int h[], int x[]) {
9+
fill_n(h, m, 0);
10+
REP(i, n) h[a[i]]++;
11+
FOR(i, 1, m) h[i] += h[i-1];
12+
ROF(i, 0, n) sa[--h[a[i]]] = i;
13+
r[sa[0]] = 0;
14+
FOR(i, 1, n) r[sa[i]] = r[sa[i-1]] + (a[sa[i]] != a[sa[i-1]]);
15+
int k = 1, l;
16+
for (; r[sa[n-1]] != n-1; k *= 2) {
17+
REP(i, n) h[r[sa[i]]] = i;
18+
ROF(i, 0, n) if (sa[i] >= k) x[h[r[sa[i]-k]]--] = sa[i]-k;
19+
FOR(i, n-k, n) x[h[r[i]]] = i;
20+
copy_n(x, n, sa);
21+
h[sa[0]] = l = 0;
22+
FOR(i, 1, n) h[sa[i]] = l += r[sa[i]] != r[sa[i-1]] || max(sa[i], sa[i-1]) >= n-k || r[sa[i]+k] != r[sa[i-1]+k];
23+
copy_n(h, n, r);
24+
}
25+
h[0] = k = 0;
26+
REP(i, n) {
27+
if (r[i]) {
28+
for (int j = sa[r[i]-1]; i+k < n && j+k < n && a[i+k] == a[j+k]; k++);
29+
h[r[i]] = k;
30+
}
31+
k && k--;
32+
}
33+
}
34+
35+
class Solution {
36+
public:
37+
int longestCommonSubpath(int n, vector<vector<int>>& paths) {
38+
int m = paths.size(), tot = 0;
39+
REP(i, m) {
40+
REP(j, paths[i].size()) {
41+
pos[tot] = i;
42+
a[tot++] = paths[i][j];
43+
}
44+
a[tot++] = n+i;
45+
}
46+
suffix_array(tot, n+m, h, x);
47+
48+
fill_n(r, m, 0);
49+
int ans = 0, cnt = 0, j = 0, hd = 0, tl = 0;
50+
REP(i, tot-m) {
51+
if (!r[pos[sa[i]]]++) cnt++;
52+
while (hd < tl && h[x[tl-1]] > h[i]) tl--;
53+
x[tl++] = i;
54+
if (cnt < m) continue;
55+
while (cnt == m) {
56+
if (!--r[pos[sa[j]]]) cnt--;
57+
if (x[hd] == j++) hd++;
58+
}
59+
ans = max(ans, h[x[hd]]);
60+
}
61+
return ans;
62+
}
63+
};

longest-common-subpath.rs

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Longest Common Subpath
2+
impl Solution {
3+
pub fn longest_common_subpath(ab: i32, mut paths: Vec<Vec<i32>>) -> i32 {
4+
let np = paths.len();
5+
let mut a = vec![];
6+
let mut pos = vec![];
7+
for i in 0..np {
8+
a.append(&mut paths[i]);
9+
a.push(ab + i as i32);
10+
pos.resize(a.len(), i as i32);
11+
}
12+
13+
let n = a.len();
14+
let m = ab as usize + np;
15+
let mut sa: Vec<i32> = Vec::with_capacity(n);
16+
let mut r: Vec<i32> = Vec::with_capacity(n);
17+
let mut h = vec![0; n.max(m)];
18+
let mut x: Vec<i32> = Vec::with_capacity(n);
19+
unsafe { sa.set_len(n); r.set_len(n); x.set_len(n); }
20+
for i in 0..n { h[a[i] as usize] += 1; }
21+
for i in 1..m { h[i] += h[i-1]; }
22+
for i in (0..n).rev() { let v = &mut h[a[i] as usize]; *v -= 1; sa[*v as usize] = i as i32; }
23+
r[sa[0] as usize] = 0;
24+
for i in 1..n { r[sa[i] as usize] = r[sa[i-1] as usize] + if a[sa[i] as usize]!=a[sa[i-1] as usize] {1} else {0}; }
25+
let mut k = 1;
26+
while r[sa[n-1] as usize] != (n-1) as i32 {
27+
for i in 0..n { h[r[sa[i] as usize] as usize] = i as i32;}
28+
for i in (0..n).rev() { if sa[i] >= k as i32 {
29+
let v = &mut h[r[sa[i] as usize-k] as usize]; x[*v as usize] = sa[i]-k as i32; *v -= 1; }}
30+
for i in n-k..n { x[h[r[i] as usize] as usize] = i as i32; }
31+
sa[0..n].clone_from_slice(&x[0..n]);
32+
h[sa[0] as usize] = 0;
33+
for i in 1..n { h[sa[i] as usize] = h[sa[i-1] as usize] +
34+
if r[sa[i] as usize]!=r[sa[i-1] as usize] || sa[i].max(sa[i-1]) as usize >= n-k ||
35+
r[sa[i] as usize+k]!=r[sa[i-1] as usize+k] {1} else {0}; }
36+
r[0..n].clone_from_slice(&h[0..n]);
37+
k *= 2;
38+
}
39+
k = 0;
40+
h[0] = 0;
41+
for i in 0..n {
42+
if r[i] > 0 {
43+
let j = sa[r[i] as usize-1] as usize;
44+
while i.max(j)+k < n && a[i+k] == a[j+k] { k += 1; }
45+
h[r[i] as usize] = k as i32;
46+
}
47+
if k > 0 { k -= 1; }
48+
}
49+
50+
for i in 0..np { r[i] = 0; }
51+
let mut ans = 0;
52+
let mut cnt = 0;
53+
let mut j = 0;
54+
let mut hd = 0;
55+
let mut tl = 0;
56+
for i in 0..n-np {
57+
let v = &mut r[pos[sa[i] as usize] as usize];
58+
if *v == 0 { cnt += 1; }
59+
*v += 1;
60+
while hd < tl && h[x[tl-1] as usize] > h[i] { tl -= 1; }
61+
x[tl] = i as i32;
62+
tl += 1;
63+
if cnt < np { continue; }
64+
while cnt == np {
65+
let v = &mut r[pos[sa[j] as usize] as usize];
66+
*v -= 1;
67+
if *v == 0 { cnt -= 1; }
68+
if x[hd] == j as i32 { hd += 1; }
69+
j += 1;
70+
}
71+
ans = ans.max(h[x[hd] as usize]);
72+
}
73+
ans
74+
}
75+
}

longest-duplicate-substring.rs

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
impl Solution {
2+
pub fn longest_dup_substring(s: String) -> String {
3+
let a = s.as_bytes();
4+
let n = a.len();
5+
let mut sa: Vec<i32> = Vec::with_capacity(n);
6+
let mut r: Vec<i32> = a.iter().map(|c| *c as i32).collect();
7+
let mut m = 128;
8+
let mut h = vec![0; n.max(m)];
9+
let mut x: Vec<i32> = Vec::with_capacity(n);
10+
unsafe { sa.set_len(n); x.set_len(n); }
11+
for i in 0..n { h[r[i] as usize] += 1; }
12+
for i in 1..m { h[i] += h[i-1]; }
13+
for i in (0..n).rev() { let v = &mut h[r[i] as usize]; *v -= 1; sa[*v as usize] = i as i32; }
14+
let mut k: usize = 1;
15+
loop {
16+
for i in 0..k { x[i as usize] = (n-k+i) as i32; }
17+
let mut j = k;
18+
for i in 0..n { if sa[i] >= k as i32 { x[j] = sa[i]-k as i32; j += 1; } }
19+
for i in 0..m { h[i] = 0; } // h[0..m].fill(0);
20+
for &i in x.iter() { h[r[i as usize] as usize] += 1; }
21+
for i in 1..m { h[i] += h[i-1]; }
22+
for &i in x.iter().rev() { let v = &mut h[r[i as usize] as usize]; *v -= 1; sa[*v as usize] = i; }
23+
for i in 0..m { h[i] = 0; } // h[0..m].fill(0);
24+
m = 1;
25+
h[sa[0] as usize] = 0;
26+
for i in 1..n {
27+
if r[sa[i] as usize] != r[sa[i-1] as usize] || sa[i].max(sa[i-1]) >= (n-k) as i32 || r[sa[i] as usize+k] != r[sa[i-1] as usize+k] { m += 1; }
28+
h[sa[i] as usize] = m as i32-1;
29+
}
30+
for i in 0..n { r[i] = h[i]; }
31+
if m == n { break; }
32+
k *= 2;
33+
}
34+
k = 0;
35+
h[0] = 0;
36+
let mut res0 = 0;
37+
let mut res1 = 0;
38+
for i in 0..n {
39+
if r[i] > 0 {
40+
let j = sa[r[i] as usize-1] as usize;
41+
while i.max(j)+k < n && a[i+k] == a[j+k] { k += 1; }
42+
h[r[i] as usize] = k as i32;
43+
if k > res1 {
44+
res0 = i;
45+
res1 = k;
46+
}
47+
if k > 0 { k -= 1; }
48+
}
49+
}
50+
s[res0..res0+res1].to_string()
51+
}
52+
}
53+
54+
/// suffix automaton
55+
impl Solution {
56+
pub fn longest_dup_substring(s: String) -> String {
57+
const AB: usize = 26;
58+
#[derive(Clone, Default)]
59+
struct Node { f: i32, c: [i32; AB], num: u8, l: i32, lc: i32 }
60+
fn add(ch: usize, pool: &mut [Node], tail: &mut usize, allo: &mut usize) {
61+
let x = *allo; *allo += 1;
62+
pool[x].l = pool[*tail].l+1;
63+
let mut p = *tail; *tail = x;
64+
while pool[p].c[ch] == 0 {
65+
pool[p].c[ch] = x as i32;
66+
if p == 0 { pool[x].f = 0; return; }
67+
p = pool[p].f as usize;
68+
}
69+
let q = pool[p].c[ch] as usize;
70+
if pool[p].l+1 == pool[q].l {
71+
pool[x].f = q as i32;
72+
} else {
73+
let r = *allo; *allo += 1;
74+
pool[r] = Node { f: pool[q].f, c: pool[q].c, l: pool[p].l+1, ..Default::default() };
75+
pool[x].f = r as i32;
76+
pool[q].f = r as i32;
77+
while pool[p].c[ch] == q as i32 {
78+
pool[p].c[ch] = r as i32;
79+
if p == 0 { break; }
80+
p = pool[p].f as usize;
81+
}
82+
}
83+
}
84+
85+
let s1 = s.as_bytes();
86+
let n = s1.len();
87+
let mut pool: Vec<Node> = vec![Default::default(); 2*n];
88+
let mut tail = 0; let mut allo = 1;
89+
for &ch in s1.iter() {
90+
add((ch-b'a') as usize, &mut pool[..], &mut tail, &mut allo);
91+
pool[tail].num = 1;
92+
}
93+
94+
let mut c = vec![0; n+1];
95+
let mut seq = vec![0; allo];
96+
for i in 0..allo { c[pool[i].l as usize] += 1; }
97+
for i in 1..=n { c[i] += c[i-1]; }
98+
for i in (0..allo).rev() { let r = &mut c[pool[i].l as usize]; *r -= 1; seq[*r] = i; }
99+
let mut res0 = 0;
100+
let mut res1 = 0;
101+
for i in (0..allo).rev() {
102+
let x = seq[i];
103+
let p = pool[x].f as usize;
104+
if p > 0 {
105+
pool[p].num = (pool[p].num+pool[x].num).min(2);
106+
}
107+
let mut lc = -1; // maxContext
108+
for ch in 0..AB {
109+
if pool[x].c[ch] > 0 {
110+
lc = lc.max(pool[pool[x].c[ch] as usize].lc);
111+
}
112+
}
113+
pool[x].lc = lc+1;
114+
if pool[x].num > 1 && pool[x].l as usize > res1 {
115+
res0 = n-pool[x].lc as usize;
116+
res1 = pool[x].l as usize;
117+
}
118+
}
119+
s[res0-res1..res0].to_string()
120+
}
121+
}

merge-bsts-to-create-single-bst.cc

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
class Solution {
2+
public:
3+
TreeNode* canMerge(vector<TreeNode*>& ts) {
4+
int n = ts.size();
5+
unordered_map<int, TreeNode *> nroot;
6+
for (TreeNode *t : ts) {
7+
if (t->left)
8+
nroot[t->left->val] = t->left;
9+
if (t->right)
10+
nroot[t->right->val] = t->right;
11+
}
12+
TreeNode *root = nullptr;
13+
for (TreeNode *t : ts) {
14+
auto it = nroot.find(t->val);
15+
if (it == nroot.end()) {
16+
if (root) return nullptr;
17+
root = t;
18+
continue;
19+
}
20+
it->second->left = t->left;
21+
it->second->right = t->right;
22+
}
23+
int c = 0, v = INT_MIN;
24+
for (auto *x = root; x; ) {
25+
if (TreeNode *y = x->left) {
26+
while (y->right && y->right != x)
27+
y = y->right;
28+
if (y->right != x) {
29+
y->right = x;
30+
x = x->left;
31+
continue;
32+
}
33+
y->right = nullptr;
34+
}
35+
if (v >= x->val) return nullptr;
36+
v = x->val;
37+
c++;
38+
x = x->right;
39+
}
40+
return c == nroot.size()+1 ? root : nullptr;
41+
}
42+
};
43+
44+
///
45+
46+
class Solution {
47+
public:
48+
map<int, TreeNode *> mp;
49+
bool ok;
50+
tuple<TreeNode *, int, int> dfs(TreeNode *x) {
51+
if (!x->left && !x->right) {
52+
auto it = mp.find(x->val);
53+
if (it != mp.end()) {
54+
x = it->second;
55+
mp.erase(it);
56+
}
57+
}
58+
int mn = x->val, mx = x->val, tmp;
59+
if (x->left) {
60+
tie(x->left, mn, tmp) = dfs(x->left);
61+
ok &= tmp < x->val;
62+
}
63+
if (x->right) {
64+
tie(x->right, tmp, mx) = dfs(x->right);
65+
ok &= x->val < tmp;
66+
}
67+
return {x, mn, mx};
68+
}
69+
TreeNode* canMerge(vector<TreeNode*>& ts) {
70+
int n = ts.size();
71+
unordered_set<int> nroot;
72+
mp.clear();
73+
for (TreeNode *t : ts) {
74+
mp[t->val] = t;
75+
if (t->left)
76+
nroot.insert(t->left->val);
77+
if (t->right)
78+
nroot.insert(t->right->val);
79+
}
80+
for (TreeNode *t : ts)
81+
if (!nroot.count(t->val)) {
82+
ok = true;
83+
mp.erase(t->val);
84+
auto *ans = get<0>(dfs(t));
85+
return ok && mp.empty() ? ans : nullptr;
86+
}
87+
return nullptr;
88+
}
89+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
impl Solution {
2+
pub fn count_distinct(a: String) -> i32 {
3+
let a = a.as_bytes();
4+
let n = a.len();
5+
let m = 127;
6+
let mut sa: Vec<i32> = Vec::with_capacity(n);
7+
let mut r: Vec<i32> = Vec::with_capacity(n);
8+
let mut h = vec![0; n.max(m)];
9+
let mut x: Vec<i32> = Vec::with_capacity(n);
10+
unsafe { sa.set_len(n); r.set_len(n); x.set_len(n); }
11+
for i in 0..n { h[a[i] as usize] += 1; }
12+
for i in 1..m { h[i] += h[i-1]; }
13+
for i in (0..n).rev() { let v = &mut h[a[i] as usize]; *v -= 1; sa[*v as usize] = i as i32; }
14+
r[sa[0] as usize] = 0;
15+
for i in 1..n { r[sa[i] as usize] = r[sa[i-1] as usize] + if a[sa[i] as usize]!=a[sa[i-1] as usize] {1} else {0}; }
16+
let mut k = 1;
17+
while r[sa[n-1] as usize] != (n-1) as i32 {
18+
for i in 0..n { h[r[sa[i] as usize] as usize] = i as i32;}
19+
for i in (0..n).rev() { if sa[i] >= k as i32 {
20+
let v = &mut h[r[sa[i] as usize-k] as usize]; x[*v as usize] = sa[i]-k as i32; *v -= 1; }}
21+
for i in n-k..n { x[h[r[i] as usize] as usize] = i as i32; }
22+
sa[0..n].clone_from_slice(&x[0..n]);
23+
h[sa[0] as usize] = 0;
24+
for i in 1..n { h[sa[i] as usize] = h[sa[i-1] as usize] +
25+
if r[sa[i] as usize]!=r[sa[i-1] as usize] || sa[i].max(sa[i-1]) as usize >= n-k ||
26+
r[sa[i] as usize+k]!=r[sa[i-1] as usize+k] {1} else {0}; }
27+
r[0..n].clone_from_slice(&h[0..n]);
28+
k *= 2;
29+
}
30+
k = 0;
31+
h[0] = 0;
32+
for i in 0..n {
33+
if r[i] > 0 {
34+
let j = sa[r[i] as usize-1] as usize;
35+
while i.max(j)+k < n && a[i+k] == a[j+k] { k += 1; }
36+
h[r[i] as usize] = k as i32;
37+
}
38+
if k > 0 { k -= 1; }
39+
}
40+
h[0..n].iter().fold((n*(n+1)/2) as i32, |acc,v| acc-v)
41+
}
42+
}

0 commit comments

Comments
 (0)