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
| class Solution { public: string s; struct Node { int l, r, prefix, suffix, val; Node() {} Node(int l, int r) : l(l), r(r), prefix(1), suffix(1), val(1) {} } tr[400000]; void build(int u, int l, int r) { tr[u] = {l, r}; if (l == r) return; int mid = l + r >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); } void update(int u, int i, char c) { if (tr[u].l == i && tr[u].r == i) { s[i - 1] = c; return; } int mid = tr[u].l + tr[u].r >> 1; if (i <= mid) update(u << 1, i, c); else update(u << 1 | 1, i, c); pushup(u); } void pushup(int u) { auto left = tr[u << 1], right = tr[u << 1 | 1]; int leftLen = left.r - left.l + 1, rightLen = right.r - right.l + 1; char leftLast = s[left.r - 1], rightFirst = s[right.l - 1]; tr[u].prefix = left.prefix, tr[u].suffix = right.suffix, tr[u].val = max(left.val, right.val); if (leftLast == rightFirst) { if (left.prefix == leftLen) tr[u].prefix = leftLen + right.prefix; if (right.prefix == rightLen) tr[u].suffix = left.suffix + rightLen; tr[u].val = max(tr[u].val, left.suffix + right.prefix); } } int query(int u, int l, int r) { if (l <= tr[u].l && tr[u].r <= r) return tr[u].val; int ans = 0, mid = tr[u].l + tr[u].r >> 1; if (l <= mid) ans = query(u << 1, l, r); if (r > mid) ans = max(ans, query(u << 1 | 1, l, r)); return ans; } vector<int> longestRepeating(string s, string queryCharacters, vector<int>& queryIndices) { int n = s.size(), k = queryIndices.size(); this->s = s; build(1, 1, n); for (int i = 0; i < n; ++i) update(1, i + 1, s[i]); vector<int> ans(k); for (int i = 0; i < k; ++i) { update(1, queryIndices[i] + 1, queryCharacters[i]); ans[i] = query(1, 1, n); } return ans; } };
|