#include <bits/stdc++.h>
#ifdef LOC
#include "debuglib.h"
#else
#define deb(...)
#define DBP(...)
#endif
using namespace std;
using ll = long long;
using vi = vector<int>;
using pii = pair<int, int>;
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define rep(i, b, e) for (int i = (b); i < (e); i++)
#define each(a, x) for (auto& a : (x))
#define all(x) (x).begin(), (x).end()
#define sz(x) int((x).size())
constexpr ll INF = 1e18;
struct Hull {
using T = ll;
struct Line {
T a, b, end;
T intersect(const Line& r) const {
if (a == r.a) return b > r.b ? INF : -INF;
ll u = b-r.b, d = r.a-a;
return u/d + ((u^d) >= 0 || !(u%d));
}
};
vector<Line> S;
Hull() { S.pb({ 0, -INF, INF }); }
void push(T a, T b) {
Line l{-a, -b, INF};
while (true) {
T e = S.back().end = S.back().intersect(l);
if (sz(S) < 2 || S[sz(S)-2].end < e) break;
S.pop_back();
}
S.pb(l);
}
T query(T x) {
auto t = *upper_bound(all(S), x, [](int l, const Line& r) { return l < r.end; });
return -t.a*x - t.b;
}
};
int n, k;
string s;
struct Frame {
Hull hull;
ll total = 0, blocks = 0, before = 0;
ll query(bool outside) {
ll p = hull.query(blocks);
if (outside) p = min(p, before);
return p+total;
}
};
ll solve(ll lambda) {
vector<Frame> stk(1);
stk[0].before = lambda;
stk[0].hull.push(0, lambda);
each(chr, s) {
if (chr == '(') {
stk.emplace_back();
auto &cur = stk.back(), &prv = stk[sz(stk)-2];
cur.before = prv.query(1);
cur.hull.push(0, cur.before+lambda);
} else if (sz(stk) > 1) {
auto &cur = stk.back(), &prv = stk[sz(stk)-2];
ll q = cur.query(0);
prv.blocks++;
prv.total += prv.blocks + cur.total;
prv.hull.push(-prv.blocks, q - prv.total + prv.blocks*prv.blocks);
stk.pop_back();
} else {
ll q = stk[0].query(1);
stk[0] = {};
stk[0].before = q;
stk[0].hull.push(0, q);
}
}
return stk.back().query(1) - lambda*k;
}
void run() {
cin >> n >> k >> s;
ll b = 0, e = 1e11;
while (b+1 < e) {
ll m = (b+e) / 2;
(solve(m-1) <= solve(m) ? b : e) = m;
}
cout << solve(b) << '\n';
}
int main() {
cin.sync_with_stdio(0); cin.tie(0);
cout << fixed << setprecision(10);
run();
cout << flush; _Exit(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 100 101 102 103 104 105 106 107 108 109 110 111 | #include <bits/stdc++.h> #ifdef LOC #include "debuglib.h" #else #define deb(...) #define DBP(...) #endif using namespace std; using ll = long long; using vi = vector<int>; using pii = pair<int, int>; #define pb push_back #define mp make_pair #define x first #define y second #define rep(i, b, e) for (int i = (b); i < (e); i++) #define each(a, x) for (auto& a : (x)) #define all(x) (x).begin(), (x).end() #define sz(x) int((x).size()) constexpr ll INF = 1e18; struct Hull { using T = ll; struct Line { T a, b, end; T intersect(const Line& r) const { if (a == r.a) return b > r.b ? INF : -INF; ll u = b-r.b, d = r.a-a; return u/d + ((u^d) >= 0 || !(u%d)); } }; vector<Line> S; Hull() { S.pb({ 0, -INF, INF }); } void push(T a, T b) { Line l{-a, -b, INF}; while (true) { T e = S.back().end = S.back().intersect(l); if (sz(S) < 2 || S[sz(S)-2].end < e) break; S.pop_back(); } S.pb(l); } T query(T x) { auto t = *upper_bound(all(S), x, [](int l, const Line& r) { return l < r.end; }); return -t.a*x - t.b; } }; int n, k; string s; struct Frame { Hull hull; ll total = 0, blocks = 0, before = 0; ll query(bool outside) { ll p = hull.query(blocks); if (outside) p = min(p, before); return p+total; } }; ll solve(ll lambda) { vector<Frame> stk(1); stk[0].before = lambda; stk[0].hull.push(0, lambda); each(chr, s) { if (chr == '(') { stk.emplace_back(); auto &cur = stk.back(), &prv = stk[sz(stk)-2]; cur.before = prv.query(1); cur.hull.push(0, cur.before+lambda); } else if (sz(stk) > 1) { auto &cur = stk.back(), &prv = stk[sz(stk)-2]; ll q = cur.query(0); prv.blocks++; prv.total += prv.blocks + cur.total; prv.hull.push(-prv.blocks, q - prv.total + prv.blocks*prv.blocks); stk.pop_back(); } else { ll q = stk[0].query(1); stk[0] = {}; stk[0].before = q; stk[0].hull.push(0, q); } } return stk.back().query(1) - lambda*k; } void run() { cin >> n >> k >> s; ll b = 0, e = 1e11; while (b+1 < e) { ll m = (b+e) / 2; (solve(m-1) <= solve(m) ? b : e) = m; } cout << solve(b) << '\n'; } int main() { cin.sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(10); run(); cout << flush; _Exit(0); } |
English