Submission #1172265

#TimeUsernameProblemLanguageResultExecution timeMemory
1172265jillCake 3 (JOI19_cake3)C++20
0 / 100
85 ms219712 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int nmax = 4e6 + 5;

struct WT {
    struct node {
        int l, r;
        vector<ll> x;
        vector<ll> s;
    } t[nmax];
    ll lo, hi;
    
    int build(vector<ll> seq, ll a, ll b) {  
        static int idx = 0;
        if(seq.empty()) return -1;
        int cur = idx++;
        if(a == b) return cur;
        int mid = (a + b) >> 1;
        t[cur].x.resize(seq.size());
        t[cur].s.resize(seq.size());
        vector<ll> left_seq, right_seq;
        for (size_t i = 0; i < seq.size(); i++) {
            if(seq[i] <= mid) {
                t[cur].x[i] = 0;
                t[cur].s[i] = 0;
                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 (size_t i = 1; i < seq.size(); 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 node, int i) {
        return i - (i >= 0 ? t[node].x[i] : 0);
    }
    int map_right(int node, int i) {
        // Số phần tử bên phải trong [0,i] là t[node].x[i]
        return (i >= 0 ? t[node].x[i] : 0) - 1;
    }
    
    int countRight(int node, int l, int r) {
        if(l > r || l < 0) return 0;
        int res = t[node].x[r];
        if(l > 0) res -= t[node].x[l-1];
        return res;
    }
    
    ll sumRight(int node, int l, int r) {
        if(l > r || l < 0) return 0LL;
        ll res = t[node].s[r];
        if(l > 0) res -= t[node].s[l-1];
        return res;
    }
    
    ll getUtil(int node, ll a, ll b, int l, int r, int k) {
        if(l > r || k <= 0) return 0LL;
        if(a == b) { 
            int cnt = r - l + 1;
            int take = min(cnt, k);
            return (ll) take * a;
        }
        int mid = (a + b) >> 1;
        int cntR = countRight(node, l, r); 
        if(cntR >= k) {
            int newL = map_right(node, l);
            int newR = map_right(node, r);
            return getUtil(t[node].r, mid+1, b, newL, newR, k);
        } else {
            ll sumR = sumRight(node, l, r);
            int newL = map_left(node, l);
            int newR = map_left(node, r);
            return sumR + getUtil(t[node].l, a, mid, newL, newR, k - cntR);
        }
    }
    
    ll get(int l, int r, int k) {
        if(l > r) return 0LL;
        return getUtil(0, lo, hi, l, r, k);
    }
} tree;

int n, m;
ll ans;
vector<array<ll, 2>> a; 

int cost(int l, int r) {
    return tree.get(l+1, r-1, m-2) - 2 * abs(a[l][1] - a[r][1]) + a[r][0] + a[l][0];
}

void calc(int l, int r, int opl, int opr) {
    if(l > r) return;
    int mid = (l + r) >> 1;
    pair<ll, int> best = {-LLONG_MAX, max(0, mid - m + 1)};
    if(mid - m + 1 >= 0) {
        for (int k = opl; k <= min(mid - m + 1, opr); k++) {
            best = max(best, { (ll) cost(k, mid), k });
        }
        ans = max(ans, best.first);
        calc(l, mid - 1, opl, best.second);
    }
    calc(mid + 1, r, best.second, opr);
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n >> m;
    a.resize(n);
    for (int i = 0; i < n; i++){
        cin >> a[i][0] >> a[i][1];
    }
    sort(a.begin(), a.end(), [](auto x, auto y) {
        return x[1] < y[1];
    });
    vector<ll> b;
    for (int i = 0; i < n; i++){
        b.push_back(a[i][0]);
    }
    ll mn = *min_element(b.begin(), b.end());
    ll mx = *max_element(b.begin(), b.end());
    tree.lo = mn;
    tree.hi = mx;
    tree.build(b, mn, mx);
    calc(0, n - 1, 0, n - 1);
    cout << ans;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...