#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100'007;
char s[MAXN];
int sum[MAXN];
vector<int> where[MAXN * 2];
pair<int, int> prev_sums[MAXN];
int prev_sums_last;
tuple<long long, int, int> dp[MAXN];
int dp_last;
void calc_dp(int n, long long penalty) {
prev_sums[0] = make_pair(sum[0], 0);
prev_sums_last = 0;
dp[0] = make_tuple(0ll, 0, 0);
dp_last = 0;
for (int i = 1; i <= n; i++) {
while (prev_sums_last >= 0 && sum[i] <= prev_sums[prev_sums_last].first) {
prev_sums_last--;
}
int bound = 0;
if (prev_sums_last >= 0) {
bound = prev_sums[prev_sums_last].second + 1;
}
prev_sums[++prev_sums_last] = make_pair(sum[i], i);
if (s[i - 1] == ')') {
int my_pos = lower_bound(where[sum[i]].begin(), where[sum[i]].end(), i) - where[sum[i]].begin();
for (int j = 0; j <= dp_last; j++) {
get<0>(dp[j]) += my_pos - (lower_bound(where[sum[i]].begin(), where[sum[i]].end(), max(bound, get<2>(dp[j]))) - where[sum[i]].begin());
}
int tmp = dp_last;
dp_last = -1;
for (int j = 0; j <= tmp; j++) {
while (dp_last >= 0 && get<0>(dp[dp_last]) >= get<0>(dp[j])) {
dp_last--;
}
assert(++dp_last <= j);
if (dp_last != j) {
dp[dp_last] = dp[j];
}
}
}
tuple<long long, int, int> me = make_tuple(get<0>(dp[0]) + penalty, get<1>(dp[0]) + 1, i);
while (dp_last >= 0 && get<0>(dp[dp_last]) >= get<0>(me)) {
dp_last--;
}
dp[++dp_last] = me;
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n >> k >> s;
sum[0] = n;
where[n].emplace_back(0);
for (int i = 1; i <= n; i++) {
if (s[i - 1] == '(') {
sum[i] = sum[i - 1] + 1;
}
else {
sum[i] = sum[i - 1] - 1;
}
where[sum[i]].emplace_back(i);
}
long long low = 0, high = 1e12 + 7;
while (low < high) {
long long mid = (low + high + 1) >> 1;
calc_dp(n, mid);
if (get<1>(dp[dp_last]) >= k) {
low = mid;
}
else {
high = mid - 1;
}
}
calc_dp(n, high);
long long result = get<0>(dp[dp_last]) - high * k;
cout << result << '\n';
return 0;
}
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 93 94 95 96 97 98 99 | #include <bits/stdc++.h> using namespace std; const int MAXN = 100'007; char s[MAXN]; int sum[MAXN]; vector<int> where[MAXN * 2]; pair<int, int> prev_sums[MAXN]; int prev_sums_last; tuple<long long, int, int> dp[MAXN]; int dp_last; void calc_dp(int n, long long penalty) { prev_sums[0] = make_pair(sum[0], 0); prev_sums_last = 0; dp[0] = make_tuple(0ll, 0, 0); dp_last = 0; for (int i = 1; i <= n; i++) { while (prev_sums_last >= 0 && sum[i] <= prev_sums[prev_sums_last].first) { prev_sums_last--; } int bound = 0; if (prev_sums_last >= 0) { bound = prev_sums[prev_sums_last].second + 1; } prev_sums[++prev_sums_last] = make_pair(sum[i], i); if (s[i - 1] == ')') { int my_pos = lower_bound(where[sum[i]].begin(), where[sum[i]].end(), i) - where[sum[i]].begin(); for (int j = 0; j <= dp_last; j++) { get<0>(dp[j]) += my_pos - (lower_bound(where[sum[i]].begin(), where[sum[i]].end(), max(bound, get<2>(dp[j]))) - where[sum[i]].begin()); } int tmp = dp_last; dp_last = -1; for (int j = 0; j <= tmp; j++) { while (dp_last >= 0 && get<0>(dp[dp_last]) >= get<0>(dp[j])) { dp_last--; } assert(++dp_last <= j); if (dp_last != j) { dp[dp_last] = dp[j]; } } } tuple<long long, int, int> me = make_tuple(get<0>(dp[0]) + penalty, get<1>(dp[0]) + 1, i); while (dp_last >= 0 && get<0>(dp[dp_last]) >= get<0>(me)) { dp_last--; } dp[++dp_last] = me; } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, k; cin >> n >> k >> s; sum[0] = n; where[n].emplace_back(0); for (int i = 1; i <= n; i++) { if (s[i - 1] == '(') { sum[i] = sum[i - 1] + 1; } else { sum[i] = sum[i - 1] - 1; } where[sum[i]].emplace_back(i); } long long low = 0, high = 1e12 + 7; while (low < high) { long long mid = (low + high + 1) >> 1; calc_dp(n, mid); if (get<1>(dp[dp_last]) >= k) { low = mid; } else { high = mid - 1; } } calc_dp(n, high); long long result = get<0>(dp[dp_last]) - high * k; cout << result << '\n'; return 0; } |
English