Submission #1228532

#TimeUsernameProblemLanguageResultExecution timeMemory
1228532LucaIlieAliens (IOI16_aliens)C++20
100 / 100
327 ms11924 KiB
#include "aliens.h"
#include <vector>
#include <stdio.h>
#include <algorithm>
#include <math.h>

using namespace std;

struct interval {
    int l, r;
    bool operator < (interval a) {
        if (l == a.l)
            return r > a.r;
        return l < a.l;
    }
};

const int MAX_N = 1e5;
const long long INF = 1e18;
int cnt[MAX_N + 1];
long long dp[MAX_N + 1];
interval v[MAX_N + 1];

struct line {
    int ind; 
    long long a, b;

    long long operator ()(int x) {
        return a * x + b;
    }
};

long long overtake(line l, line m) {
    long long t = ceil((double)(m.b - l.b) / (l.a - m.a));
    return t;
}

struct CHT {
    vector<pair<long long, line>> lines;

    void clear() {
        lines.clear();
    }

    void addLine(line l) {
        while (!lines.empty() && overtake(l, lines.back().second) < lines.back().first)
            lines.pop_back();
        long long t = (lines.empty() ? 0 : overtake(l, lines.back().second));
        lines.push_back({t, l});
    }

    int getMin(int x) {
        int l = 0, r = lines.size();
        while (r - l > 1) {
            int mid = (l + r) / 2;
            if (lines[mid].first > x)
                r = mid;
            else
                l = mid;
        }

        return lines[l].second.ind;
    }
};

const int BASE = 1e5 + 1;

void computeDp(int n, long long coef) {
    CHT cht;
    for (int i = 1; i <= n; i++) {
        long long overI = max(0, (v[i - 1].r - v[i].l));
        line a;
        a.ind = i;
        a.a = -2LL * v[i].l * BASE;
        a.b = (long long)dp[i - 1] + (long long)v[i].l * v[i].l - overI * overI;
        a.b = a.b * BASE + cnt[i - 1];
        cht.addLine(a);

        int j = cht.getMin(v[i].r);
        long long len = (v[i].r - v[j].l);
        long long over = max(0, (v[j - 1].r - v[j].l));
        long long cost = dp[j - 1] + len * len - over * over + coef;
        dp[i] = cost;
        cnt[i] = cnt[j - 1] + 1;
        // printf("%d %d\n", v[i].l, v[i].r);
        // printf("%d\n", j);
    }

    // printf("%lld %lld %d\n", coef, dp[n], cnt[n]);
}

long long take_photos(int n, int m, int k, vector<int> R, vector<int> C) {
    vector<interval> rc(n);
    for (int i = 0; i < n; i++) {
        if (R[i] > C[i])
            swap(R[i], C[i]);
        C[i]++;
        rc[i] = {R[i], C[i]};
    }

    sort(rc.begin(), rc.end());

    n = 0;
    int maxR = -1;
    for (interval a: rc) {
        if (a.r > maxR) {
            v[++n] = a;
            maxR = a.r;
        }
    }
    k = min(k, n);

    long long lb = 0, rb = 1e12;
    while (rb - lb > 1) {
        long long coef = (lb + rb) / 2;
        computeDp(n, coef);

        if (cnt[n] > k)
            lb = coef;
        else
            rb = coef;
    }
    computeDp(n, rb);

    return dp[n] - rb * k;
}

Compilation message (stderr)

aliens.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
aliens_c.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
#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...