Submission #1172238

#TimeUsernameProblemLanguageResultExecution timeMemory
1172238jillCake 3 (JOI19_cake3)C++20
0 / 100
124 ms219684 KiB
#include <bits/stdc++.h> using namespace std; #define fi first #define se second using ll = long long; using pii = pair<ll, ll>; const ll maxn = 4e6 + 5, inf = 1e9, oo = 1e18; ll n, m, dp[2][maxn]; pii a[maxn]; struct WT { struct node { int l, r; vector<ll> x; vector<ll> s; } t[maxn]; int build(vector<ll> &seq, ll a = 0, ll b = inf) { static int idxNode = 0; if (seq.empty()) return -1; int cur = idxNode++; if (a == b) return cur; t[cur].x.resize(seq.size()); t[cur].s.resize(seq.size()); ll mid = (a + b) / 2; vector<ll> left_seq, right_seq; for (int i = 0; i < (int)seq.size(); i++) { if (seq[i] <= mid) { left_seq.push_back(seq[i]); } else { t[cur].x[i] = 1; t[cur].s[i] = seq[i]; right_seq.push_back(seq[i]); } } for (int i = (int)seq.size() - 2; i >= 0; i--) { t[cur].x[i] += t[cur].x[i + 1]; t[cur].s[i] += t[cur].s[i + 1]; } t[cur].l = build(left_seq, a, mid); t[cur].r = build(right_seq, mid + 1, b); return cur; } int map_left(int nd, int i) { return i >= 0 ? i - t[nd].x[i] : -1; } int map_right(int nd, int i) { return i >= 0 ? t[nd].x[i] - 1 : -1; } int countRight(int cur, int l, int r) { if (l > r) return 0; ll totalR = t[cur].x[l]; ll beyond = (r + 1 < (int)t[cur].x.size()) ? t[cur].x[r + 1] : 0; return (int)(totalR - beyond); } int64_t sumRight(int cur, int l, int r) { if (l > r) return 0LL; ll totalR = t[cur].s[l]; ll beyond = (r + 1 < (int)t[cur].s.size()) ? t[cur].s[r + 1] : 0LL; return (totalR - beyond); } ll queryUtil(int node, int a, int b, int l, int r, int k) { if (node == -1 || l > r || k <= 0) return 0LL; if (a == b) { int countSeg = (r - l + 1); int take = min(countSeg, k); return 1LL * take * a; } int mid = (a + b) >> 1; int totalR = countRight(node, l, r); if (totalR >= k) { int newL = map_right(node, l - 1) + 1; int newR = map_right(node, r); return queryUtil(t[node].r, mid + 1, b, newL, newR, k); } else { ll sumR = sumRight(node, l, r); int newL = map_left(node, l - 1) + 1; int newR = map_left(node, r); return sumR + queryUtil(t[node].l, a, mid, newL, newR, k - totalR); } } ll query(int l, int r, int k) { if (l > r) return 0LL; return queryUtil(0, 0, inf, l, r, k); } } tree; void calc(int x, int l, int r, int opl, int opr) { if (l > r) return; int mid = l + r >> 1; pii best = {-oo, -1}; for (int k = opl; k < min(mid, opr); k++) { best = max(best, {tree.query(k + 1, mid - 1, m - 2) + a[mid].fi + a[k].fi - 2 * abs(a[mid].se - a[k].se), k}); } dp[x][mid] = best.fi; int opt = best.se; calc(x, l, mid - 1, opl, opt); calc(x, mid + 1, r, opt, opr); } vector<ll> b; signed main() { cin >> n >> m; for (int i = 0; i < n; i++) { cin >> a[i].fi >> a[i].se; } sort(a, a + n, [](auto x, auto y) { return x.se < y.se; }); for (int i = 0; i < n; i++) { dp[0][i] = a[i].fi - a[i].se; b.push_back(a[i].fi); } tree.build(b); calc(1, 0, n - 1, 0, n - 1); cout << *max_element(dp[1], dp[1] + n); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...