Submission #940822

#TimeUsernameProblemLanguageResultExecution timeMemory
940822PanndaAliens (IOI16_aliens)C++17
100 / 100
530 ms7312 KiB
#include "aliens.h"

#include <bits/stdc++.h>
using namespace std;

long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
    auto [fl, fr] = [&]() -> array<vector<long long>, 2> {
        vector<array<int, 2>> fetch;
        for (int i = 0; i < n; i++) {
            fetch.push_back({min(r[i], c[i]), max(r[i], c[i]) + 1});
        }
        sort(fetch.begin(), fetch.end(), [&](array<int, 2> lr0, array<int, 2> lr1) {
             if (lr0[0] != lr1[0]) return lr0[0] < lr1[0];
             return lr0[1] > lr1[1];
        });
        vector<long long> fl, fr;
        for (auto [l, r] : fetch) {
            if (!fr.empty() && fr.back() >= r) continue;
            fl.push_back(l);
            fr.push_back(r);
        }
        return {fl, fr};
    }();
    n = fl.size();
    k = min(n, k);

    auto getExtremum = [&](long long lambda) -> pair<long long, int> {
        auto cost = [&](int j, int i) -> long long {
            long long d = max(0LL, j == 0 ? 0LL : fr[j - 1] - fl[j]);
            return (fr[i - 1] - fl[j]) * (fr[i - 1] - fl[j]) - d * d + lambda;
        };
        vector<long long> dp(n + 1);
        vector<int> arg(n + 1);
        dp[0] = arg[0] = 0;
        deque<array<int, 2>> deq = { {0, 1} };
        for (int i = 1; i <= n; i++) {
            if (deq.size() >= 2 && deq[1][1] == i) deq.pop_front();

            int j = deq.front()[0];
            dp[i] = dp[j] + cost(j, i);
            arg[i] = arg[j] + 1;
            if (i == n) break;

            while (!deq.empty()) {
                int j = deq.back()[0];
                int k = max(i + 1, deq.back()[1]);
                if (dp[i] + cost(i, k) < dp[j] + cost(j, k)) {
                    deq.pop_back();
                } else {
                    break;
                }
            }

            if (deq.empty()) {
                deq.push_back({i, i + 1});
            } else {
                int l = max(i + 1, deq.back()[1]), r = n + 1;
                int j = deq.back()[0];
                while (l < r) {
                    int m = (l + r) >> 1;
                    if (dp[i] + cost(i, m) < dp[j] + cost(j, m)) {
                        r = m;
                    } else {
                        l = m + 1;
                    }
                }
                if (l <= n) {
                    deq.push_back({i, l});
                }
            }
        }
        return make_pair(dp[n], arg[n]);
    };

    long long lambda = [&]() -> long long {
        long long l = 0, r = 1e18;
        while (l < r) {
            long long m = (l + r) >> 1;
            auto [extre, arg] = getExtremum(m);
            if (arg <= k) {
                r = m;
            } else {
                l = m + 1;
            }
        }
        return l;
    }();

    auto [extre, arg] = getExtremum(lambda);
    return extre - lambda * k;
}
#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...