Submission #1184091

#TimeUsernameProblemLanguageResultExecution timeMemory
1184091OI_AccountCake 3 (JOI19_cake3)C++20
100 / 100
3349 ms19936 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 200'000;
const ll INF = 1'000'000'000'000'000;
const int S = 2 * N;

int n, k;
ll v[N + 10], c[N + 10], segVal[N + 10];
int id[N + 10], cnt[4 * N + 10];
ll seg[4 * N + 10], ans[N + 10];
pair<ll, ll> p[N + 10];

int opl[S + 10], opr[S + 10];
int ql[S + 10], qr[S + 10], q;
int lft, rght;

void readInput() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
        cin >> p[i].second >> p[i].first;
}

void calcVC() {
    sort(p + 1, p + n + 1);
    for (int i = 1; i <= n; i++) {
        v[i] = p[i].second;
        c[i] = p[i].first;
    }
}

void calcId() {
    for (int i = 1; i <= n; i++)
        p[i] = {v[i], i};
    sort(p + 1, p + n + 1);
    for (int i = 1; i <= n; i++) {
        segVal[i] = p[i].first;
        id[p[i].second] = i;
    }
}

ll get(int k, int id = 1, int l = 1, int r = n + 1) {
    if (l + 1 == r)
        return seg[id];
    int mid = (l + r) >> 1;
    if (cnt[id << 1 | 1] < k)
        return seg[id << 1 | 1] + get(k - cnt[id << 1 | 1], id << 1, l, mid);
    return get(k, id << 1 | 1, mid, r);
}

void update(int idx, int id = 1, int l = 1, int r = n + 1) {
    if (idx < l || r <= idx)
        return;
    if (l + 1 == r) {
        cnt[id] = 1 ^ cnt[id];
        seg[id] = segVal[l] * cnt[id];
        return;
    }
    int mid = (l + r) >> 1;
    update(idx, id << 1, l, mid);
    update(idx, id << 1 | 1, mid, r);
    seg[id] = seg[id << 1] + seg[id << 1 | 1];
    cnt[id] = cnt[id << 1] + cnt[id << 1 | 1];
}

ll getAns(int l, int r) {
    while (l < lft) 
        update(id[lft--]);
    while (rght < r)
        update(id[rght++]);
    while (lft < l)
        update(id[++lft]);
    while (r < rght)
        update(id[--rght]);
    if (rght - lft + 1 < k)
        return -INF;
    return get(k - 2) + v[lft] + v[rght] - 2ll * (c[rght] - c[lft]);
}

void addQu(int a, int b, int c, int d) {
    q++;
    opl[q] = a; opr[q] = b;
    ql[q] = c; qr[q] = d;
}

void solve(int optL, int optR, int l, int r) {
    int mid = (l + r) >> 1;
    ans[mid] = getAns(optL, mid);
    int opt = optL;
    for (int i = optL + 1; i <= optR && i < mid; i++) {
        ll tmp = getAns(i, mid);
        if (tmp > ans[mid]) {
            ans[mid] = tmp;
            opt = i;
        }
    }
    if (l < mid)
        addQu(optL, opt, l, mid - 1);
    if (mid < r)
        addQu(opt, optR, mid + 1, r);
}

void calcAns() {
    addQu(1, n, 1, n);
    for (int i = 1; i <= q; i++)
        solve(opl[i], opr[i], ql[i], qr[i]);
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    readInput();
    calcVC();
    calcId();
    calcAns();
    cout << *max_element(ans + 1, ans + n + 1);
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...