forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
maximum-segment-sum-after-removals.cpp
92 lines (85 loc) · 2.64 KB
/
maximum-segment-sum-after-removals.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Time: O(n)
// Space: O(n)
// union find
class Solution {
public:
vector<long long> maximumSegmentSum(vector<int>& nums, vector<int>& removeQueries) {
vector<long long> result(size(nums));
vector<bool> lookup(size(nums));
UnionFind uf(nums);
for (int i = size(removeQueries) - 1; i >= 1; --i) {
const int q = removeQueries[i];
lookup[q] = true;
if (q - 1 >= 0 && lookup[q - 1]) {
uf.union_set(q - 1, q);
}
if (q + 1 < size(lookup) && lookup[q + 1]) {
uf.union_set(q, q + 1);
}
result[i - 1] = max(result[i], uf.total(q));
}
return result;
}
private:
class UnionFind {
public:
UnionFind(const vector<int>& nums)
: set_(size(nums))
, rank_(size(nums))
, size_(cbegin(nums), cend(nums)) {
iota(set_.begin(), set_.end(), 0);
}
int find_set(int x) {
if (set_[x] != x) {
set_[x] = find_set(set_[x]); // Path compression.
}
return set_[x];
}
bool union_set(int x, int y) {
x = find_set(x), y = find_set(y);
if (x == y) {
return false;
}
if (rank_[x] > rank_[y]) {
swap(x, y);
}
set_[x] = y; // Union by rank.
if (rank_[x] == rank_[y]) {
++rank_[y];
}
size_[y] += size_[x];
return true;
}
long long total(int x) {
return size_[find_set(x)];
}
private:
vector<int> set_;
vector<int> rank_;
vector<long long> size_;
};
};
// Time: O(nlogn)
// Space: O(n)
// prefix sum, bst
class Solution2 {
public:
vector<long long> maximumSegmentSum(vector<int>& nums, vector<int>& removeQueries) {
set<int> removed_idxs = {-1, static_cast<int>(size(nums))};
vector<long long> prefix(size(nums) + 1);
for (int i = 0; i < size(nums); ++i) {
prefix[i + 1] = prefix[i] + nums[i];
}
multiset<long long> segments = {prefix.back()};
vector<long long> result;
for (const auto& q : removeQueries) {
const auto it = removed_idxs.emplace(q).first;
const int left = *prev(it), right = *next(it);
segments.erase(segments.find(prefix[right] - prefix[left + 1]));
segments.emplace(prefix[q] - prefix[left + 1]);
segments.emplace(prefix[right] - prefix[q + 1]);
result.emplace_back(*rbegin(segments));
}
return result;
}
};