intfind(int x){ int root = x; while (parent[root] != root) root = parent[root]; while (parent[x] != x) { int next = parent[x]; parent[x] = root; x = next; } return root; }
voidunite(int a, int b){ a = find(a); b = find(b); if (a == b) return; if (size[a] < size[b]) swap(a, b); parent[b] = a; size[a] += size[b]; left[a] = min(left[a], left[b]); right[a] = max(right[a], right[b]); }
voiderase(int x){ if (removed[x]) return; removed[x] = true; if (x > 1 && removed[x - 1]) unite(x, x - 1); if (x < n && removed[x + 1]) unite(x, x + 1); }
pair<int, int> nearestAlive(int x){ int root = find(x); // x is removed when this is called return {left[root] - 1, right[root] + 1}; } };
int64 kthLargest(const vector<int>& a, int64 k){ int n = static_cast<int>(a.size()) - 1; vector<int> L(n + 1), R(n + 1), st;
// Previous strictly smaller element. for (int i = 1; i <= n; ++i) { while (!st.empty() && a[st.back()] >= a[i]) st.pop_back(); L[i] = st.empty() ? 1 : st.back() + 1; st.push_back(i); }
// Next smaller-or-equal element. st.clear(); for (int i = n; i >= 1; --i) { while (!st.empty() && a[st.back()] > a[i]) st.pop_back(); R[i] = st.empty() ? n : st.back() - 1; st.push_back(i); }