Submission #778642

#TimeUsernameProblemLanguageResultExecution timeMemory
778642dooweyAliens (IOI16_aliens)C++14
100 / 100
239 ms12716 KiB
#include "aliens.h"
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef long double ld;

#define fi first
#define se second
#define mp make_pair

const ld inf = (ld)1e18;


struct line{
    ll ai;
    ll bi;
    int cn;
    ld lim;
};

vector<line> hull;

ld inter(line aa, line bb){
    return (ld)(aa.bi - bb.bi) / (ld)(bb.ai - aa.ai);
}

void put_line(ll aa, ll bb, int c){
    aa=-aa;
    bb=-bb; // assume a is increasing
    line nw = {aa, bb, c, inf};
    line l1, l2;
    while(hull.size() >= 2){
        l1 = hull[hull.size() - 2];
        l2 = hull[hull.size() - 1];
        if(inter(l1, l2) >= inter(l2, nw)) {
            hull.pop_back();
        }
        else{
            break;
        }
    }
    if(!hull.empty()) hull.back().lim=inter(hull.back(), nw);
    hull.push_back(nw);
}

pair<ll, int> query(ll xi){
    int l = 0;
    int r = (int)hull.size() - 1;
    int mid;
    while(l < r){
        mid = (l + r) / 2;
        if(hull[mid].lim < xi){
            l=mid + 1;
        }
        else{
            r=mid;
        }
    }
    return mp(-xi * 1ll * hull[l].ai - hull[l].bi, hull[l].cn);
}

const int N = (int)1e5 + 10;
vector<pii> T;
ll dp[N];
int cnt[N];

ll sq(ll x){
    return x * 1ll * x;
}

void compute(int n, int k, ll penalty){
    dp[0]=cnt[0]=0;
    hull.clear();
    for(int i = 1; i < n; i ++ ){
        dp[i]=inf;
    }
    ll B;
    pair<ll, int> ndp;
    for(int i = 1 ; i < n; i ++ ){
        B = sq(max(T[i - 1].se - T[i].fi, 0));
        put_line(-2ll * T[i].fi, sq(T[i].fi) + dp[i - 1] - B, cnt[i - 1]);
        ndp = query(T[i].se);
        ndp.fi += sq(T[i].se) + penalty;
        ndp.se ++ ;
        dp[i] = ndp.fi;
        cnt[i] = ndp.se;
    }
}


ll take_photos(int n, int m, int k, vector<int> r, vector<int> c) {
    vector<pii> segt;
    for(int i = 0 ; i < n ; i ++ ){
        segt.push_back(mp(min(r[i], c[i]), max(r[i],c[i])));
    }
    sort(segt.begin(), segt.end(), [&](pii i, pii j){
        if(i.fi == j.fi){
            return i.se > j.se;
        }
        else{
            return i.fi < j.fi;
        }
    });
    T.push_back(mp(-1,-1));
    for(auto x : segt){
        if(x.se > T.back().se){
            T.push_back(x);
        }
    }
    n=T.size();
    for(int i = 1; i < n; i ++ ) T[i].fi -- ;
    k=min(k,n-1);
    ll lf = 0ll, rf = m * 1ll * m + 100;
    ll mid;
    while(lf < rf){
        mid = (lf + rf) / 2;
        compute(n, k, mid);
        if(cnt[n - 1] <= k){
            rf=mid;
        }
        else{
            lf=mid+1;
        }
    }
    compute(n, k, lf);
    return dp[n-1] - k * 1ll * lf;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...