Skip to content

Commit 91ea4ae

Browse files
authored
Update longest-substring-of-one-repeating-character.cpp
1 parent 4c92086 commit 91ea4ae

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

C++/longest-substring-of-one-repeating-character.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ class Solution {
6464
return update(s[i]);
6565
};
6666
const auto& query = [] (const auto& x, const auto& y) {
67+
if (x.len == 0) {
68+
return y;
69+
}
6770
if (y.len == 0) {
6871
return x;
6972
}
@@ -83,3 +86,113 @@ class Solution {
8386
return result;
8487
}
8588
};
89+
90+
// Time: O(nlogn)
91+
// Space: O(n)
92+
93+
template <typename Node, typename T>
94+
class SegmentTree2 {
95+
public:
96+
explicit SegmentTree2(
97+
int N,
98+
const function<Node(const int&)>& build_fn,
99+
const function<Node(const T&)>& update_fn,
100+
const function<Node(const Node&, const Node&)>& query_fn)
101+
: tree_(N > 1 ? 1 << (__lg(N - 1) + 2) : 2),
102+
base_(N > 1 ? 1 << (__lg(N - 1) + 1) : 1),
103+
build_fn_(build_fn),
104+
query_fn_(query_fn),
105+
update_fn_(update_fn) {
106+
107+
for (int i = base_; i < base_ + N; ++i) {
108+
tree_[i] = build_fn_(i - base_);
109+
}
110+
for (int i = base_ - 1; i >= 1; --i) {
111+
tree_[i] = query_fn_(tree_[2 * i], tree_[2 * i + 1]);
112+
}
113+
}
114+
115+
void update(int i, const T& h) {
116+
int x = base_ + i;
117+
tree_[x] = update_fn_(h);
118+
while (x > 1) {
119+
x /= 2;
120+
tree_[x] = query_fn_(tree_[x * 2], tree_[x * 2 + 1]);
121+
}
122+
}
123+
124+
Node query(int L, int R) {
125+
Node none;
126+
if (L > R) {
127+
return none;
128+
}
129+
L += base_;
130+
R += base_;
131+
auto left = none;
132+
auto right = none;
133+
for (; L <= R; L /= 2, R /= 2) {
134+
if (L & 1) {
135+
left = query_fn_(left, tree_[L]);
136+
++L;
137+
}
138+
if ((R & 1) == 0) {
139+
right = query_fn_(tree_[R], right);
140+
--R;
141+
}
142+
}
143+
return query_fn_(left, right);
144+
}
145+
146+
private:
147+
vector<Node> tree_;
148+
int base_;
149+
const function<Node(const int&)> build_fn_;
150+
const function<Node(const T&)> update_fn_;
151+
const function<Node(const Node&, const Node&)> query_fn_;
152+
};
153+
154+
// segment tree
155+
class Solution2 {
156+
public:
157+
vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) {
158+
struct Node {
159+
Node(char left = 0, char right = 0, int left_len = 0, int right_len = 0, int len = 0, int max_len = 0)
160+
: left(left), right(right), left_len(left_len), right_len(right_len), len(len), max_len(max_len) {
161+
}
162+
163+
char left;
164+
char right;
165+
int left_len;
166+
int right_len;
167+
int len;
168+
int max_len;
169+
};
170+
const auto& update = [] (const auto& c) {
171+
return Node(c, c, 1, 1, 1, 1);
172+
};
173+
const auto& build = [&s, &update] (const auto& i) {
174+
return update(s[i]);
175+
};
176+
const auto& query = [] (const auto& x, const auto& y) {
177+
if (x.len == 0) {
178+
return y;
179+
}
180+
if (y.len == 0) {
181+
return x;
182+
}
183+
return Node(x.left,
184+
y.right,
185+
x.left_len + ((x.left_len == x.len && x.right == y.left) ? y.left_len : 0),
186+
y.right_len + ((y.right_len == y.len && y.left == x.right) ? x.right_len : 0),
187+
x.len + y.len,
188+
max({x.max_len, y.max_len, (x.right == y.left) ? x.right_len + y.left_len : 0}));
189+
};
190+
vector<int> result;
191+
SegmentTree2<Node, char> st(size(s), build, update, query);
192+
for (int i = 0; i < size(queryCharacters); ++i) {
193+
st.update(queryIndices[i], queryCharacters[i]);
194+
result.emplace_back(st.query(0, size(s) - 1).max_len);
195+
}
196+
return result;
197+
}
198+
};

0 commit comments

Comments
 (0)