Submission #1368367

#TimeUsernameProblemLanguageResultExecution timeMemory
1368367anteknneCake 3 (JOI19_cake3)C++20
0 / 100
0 ms360 KiB
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;

#define pb push_back
#define pii pair<int, int>
#define pll pair<ll, ll>
#define st first
#define nd second
#define ordered_set tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
#define debug false

const int MAXN = 200 * 1000 + 17;
const int MAXLOG = 20;
const ll INF = ll(-1000 * 1000 * 1000) * ll(1000 * 1000 * 1000);
pii a[MAXN];
pair<int, ll> pst[4 * MAXN * MAXLOG];
int l[4 * MAXN * MAXLOG];
int r[4 * MAXN * MAXLOG];
int korzen[MAXN];
ll wyn[MAXN];
vector<int> vec;
int cnt = 0;
int M;

int f (int x) {
    return lower_bound(vec.begin(), vec.end(), x) - vec.begin();
}

void buduj (int p, int k, int i) {
    cnt = max(cnt, i);
    if (p == k) {
        return;
    }
    int sr = (p + k)/ 2;
    l[i] = i * 2;
    r[i] = i * 2 + 1;
    buduj(p, sr, i * 2);
    buduj(sr + 1, k, i * 2 + 1);
}

void lacz (int i) {
    pst[i].st = pst[l[i]].st + pst[r[i]].st;
    pst[i].nd = pst[l[i]].nd + pst[r[i]].nd;
}

void aktualizuj (int p, int k, int ind, ll w, int i, int i2) {
    pst[i] = pst[i2];
    if (p == k) {
        pst[i].st ++;
        pst[i].nd += w;
        return;
    }
    int sr = (p + k)/ 2;
    if (ind <= sr) {
        r[i] = r[i2];
        cnt ++;
        l[i] = cnt;
        aktualizuj(p, sr, ind, w, cnt, l[i2]);
    } else {
        l[i] = l[i2];
        cnt ++;
        r[i] = cnt;
        aktualizuj(sr + 1, k, ind, w, cnt, r[i2]);
    }
    lacz(i);
}

ll odczytaj (int p, int k, int m, int i, int i2) {
    if ((pst[i].st - pst[i2].st) == m) {
        return (pst[i].nd - pst[i2].nd);
    }
    if (p == k) {
        return ll(m) * ll(vec[p]);
    }
    int sr = (p + k)/ 2;
    if ((pst[r[i]].st - pst[r[i2]].st) >= m) {
        return odczytaj(sr + 1, k, m, r[i], r[i2]);
    } else {
        return (pst[r[i]].nd - pst[r[i2]].nd) + odczytaj(p, sr, m - (pst[r[i]].st - pst[r[i2]].st), l[i], l[i2]);
    }
}

ll licz (int p, int k) {
    return odczytaj(0, int(vec.size()) - 1, M, korzen[k], korzen[p - 1]) - 2LL * (a[k].st - a[p].st);
}

void dziel (int p, int k, int a, int b) {
    if (p > k) {
        return;
    }
    int sr = (p + k)/ 2;
    int ind = 0;
    for (int i = a; i <= b; i ++) {
        if ((sr - i + 1) < M) {
            break;
        }
        ll w = licz(i, sr);
        if (w > wyn[sr]) {
            wyn[sr] = w;
            ind = i;
        }
    }

    dziel(p, sr - 1, a, ind);
    dziel(sr + 1, k, ind, b);
}

int main () {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n;
    cin >> n >> M;

    for (int i = 1; i <= n; i ++) {
        cin >> a[i].nd >> a[i].st;
    }

    sort(a + 1, a + n + 1);

    for (int i = 1; i <= n; i ++) {
        vec.pb(a[i].nd);
    }
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    int k = int(vec.size());

    buduj(0, k - 1, 1);
    korzen[0] = 1;
    for (int i = 1; i <= n; i ++) {
        cnt ++;
        korzen[i] = cnt;
        aktualizuj(0, k - 1, f(a[i].nd), a[i].nd, korzen[i], korzen[i - 1]);
    }

    for (int i = 1; i <= n; i ++) {
        wyn[i] = INF;
    }
    dziel(1, n, 1, n);

    ll w = INF;
    for (int i = 1; i <= n; i ++) {
        w = max(w, wyn[i]);
    }

    cout << w << "\n";

    return 0;
}


#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...