Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Since is a subsequence of , it can never be longer than . So the “better because longer” rule is useless here. The first difference must be a position where has ( and has ).
The only length- subsequence is itself, and is not better than itself. Any useful answer must delete at least one ( and one ), so its length is at most .
If some ) in has two ( characters after it, try deleting that ) and the later of those two ( characters. The earlier later ( shifts left and creates the lexicographic win.
Deleting a ) before deleting a later ( is balance-friendly: prefix balances first increase by , then return to what they were. Since was regular, the new sequence stays regular.
So the whole problem is just checking whether )(( is a subsequence of . If yes, the answer is ; if not, no better regular subsequence exists at any length.
Because is a subsequence of , we always have . So the first rule for being better, where is a proper prefix of , cannot happen. The only possible win is lexicographic: at the first position where and differ, must have ( and must have ).
The length- subsequence of is only itself, and it is not better than itself. Also, every regular bracket sequence has the same number of ( and ). Therefore any valid better subsequence must delete at least one opening bracket and one closing bracket, so the maximum possible answer is at most
Now we prove exactly when this upper bound is achievable.
Suppose there is a ) in with at least two ( characters after it. In other words, contains )(( as a subsequence. Let:
and choose to be the first ( after . Build by deleting positions and .
The length is clearly , and the total balance is still because we deleted one ) and one (.
Why is still regular? Deleting the earlier ) increases all affected prefix balances by . Later, deleting the ( at decreases the balance back by . So no prefix balance ever becomes smaller than the corresponding prefix balance in . Since was regular, is regular too. Nice, no hidden nonsense.
Why is better than ? Since is the first ( after , all characters from to are ). After deleting , those ) characters just shift left and still match for a while. Then shifts into a position where still has ). That is the first difference, and it is exactly the good kind: has ( while has ).
So if )(( is a subsequence, answer .
Now prove the other direction. Assume a better regular subsequence exists, and let be the first position where . Then
That ( in must come from some position after in , so there is at least one ( after .
There must actually be at least two. If there were only one ( after , then the first characters of would already use every opening bracket of : the first characters match , and uses the only later opening bracket. Since is a proper subsequence, it deletes something. But if it deletes no opening bracket, it deletes only closing brackets, so its numbers of ( and ) cannot be equal. That is impossible for a regular bracket sequence.
Therefore has at least two ( characters after it. So )(( must be a subsequence.
The algorithm is now tiny:
Scan from right to left and keep , the number of ( characters strictly to the right of the current position. If we ever see a ) with , print . Otherwise print .
Complexity is
per test case and extra memory. Across all tests, this is .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
string s;
cin >> n >> s;
int opensRight = 0;
bool possible = false;
for (int i = n - 1; i >= 0; --i) {
if (s[i] == '(') {
++opensRight;
} else if (opensRight >= 2) {
possible = true;
}
}
cout << (possible ? n - 2 : -1) << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
string s;
cin >> n >> s;
int opensRight = 0;
bool possible = false;
for (int i = n - 1; i >= 0; --i) {
if (s[i] == '(') {
++opensRight;
} else if (opensRight >= 2) {
possible = true;
}
}
cout << (possible ? n - 2 : -1) << '\n';
}
}