Submission #788352

#TimeUsernameProblemLanguageResultExecution timeMemory
788352AlcabelAliens (IOI16_aliens)C++17
60 / 100
2050 ms9784 KiB
#include <bits/stdc++.h>
#ifndef LOCAL
#include "aliens.h"
#endif
using namespace std;

struct Line {
    int a;
    long long b;
    Line() {}
    Line(int _a, long long _b) {
        a = _a, b = _b;
    }
    long long f(int x) {
        return a * 1ll * x + b;
    }
    ~Line() {}
};

int sign(long long x) {
    if (x > 0) { return 1; }
    if (x < 0) { return -1; }
    return 0;
}

long long intersect(const Line& A, const Line& B) {
    // x = (B.b - A.b) / (A.a - B.a)
    long long numer = B.b - A.b, denom = A.a - B.a;
    int sn = sign(numer), sd = sign(denom);
    numer *= sn, denom *= sd;
    if (sn * sd < 0) {
        return numer / denom * -1;
    }
    return (numer + denom - 1) / denom;
}

long long take_photos(int n, int m, int k, vector<int> rows, vector<int> cols) {
    vector<int> maxRight(m, -1);
    for (int i = 0; i < n; ++i) {
        int l = min(rows[i], cols[i]);
        int r = max(rows[i], cols[i]);
        maxRight[l] = max(maxRight[l], r + 1);
    }
    vector<pair<int, int>> segs;
    for (int l = 0; l < m; ++l) {
        if (maxRight[l] != -1 && (segs.empty() || segs.back().second < maxRight[l])) {
            segs.emplace_back(l, maxRight[l]);
        }
    }
    n = segs.size();
    k = min(k, n);
    /*cerr << n << '\n';
    for (const auto& [l, r] : segs) {
        cerr << l << ' ' << r << '\n';
    }
    cerr << '\n';*/
    vector<vector<long long>> dp(2, vector<long long>(n));
    int layer = 0;
    for (int i = 0; i < n; ++i) {
        dp[layer][i] = (segs[i].second - segs[0].first) * 1ll * (segs[i].second - segs[0].first);
    }
    long long ans = dp[layer][n - 1];
    // cerr << "ans: " << ans << '\n';
    vector<Line> lines;
    vector<long long> optX;
    for (int g = 2; g <= k; ++g) {
        // cerr << "g: " << g << '\n';
        layer ^= 1;
        lines.clear();
        optX.clear();
        for (int i = g - 1, ptr = 0; i < n; ++i) {
            // cerr << "i: " << i << '\n';
            int lenInter = max(0, segs[i - 1].second - segs[i].first);
            Line l(-2 * segs[i].first, dp[layer ^ 1][i - 1] - lenInter * 1ll * lenInter + segs[i].first * 1ll * segs[i].first);
            while (!lines.empty() && intersect(lines.back(), l) <= optX.back()) {
                optX.pop_back();
                lines.pop_back();
            }
            if (!lines.empty()) {
                optX.emplace_back(intersect(lines.back(), l));
            } else {
                optX.emplace_back(-1);
            }
            lines.emplace_back(l);
            // cerr << "inserted!\n";
            ptr = min(ptr, (int)lines.size() - 1);
            while (ptr + 1 < (int)lines.size() && optX[ptr + 1] <= segs[i].second) {
                ++ptr;
            }
            // cerr << "found!\n";
            dp[layer][i] = lines[ptr].f(segs[i].second) + segs[i].second * 1ll * segs[i].second;
        }
        ans = min(ans, dp[layer][n - 1]);
    }
    return ans;
}
/*
void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    vector<int> r(n), c(n);
    for (int i = 0; i < n; ++i) {
        cin >> r[i] >> c[i];
    }
    cout << take_photos(n, m, k, r, c) << '\n';
}

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

#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
        cerr << "-----------\n";
        cout << "-----------\n";
    }
#else
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
    }
#endif

    return 0;
}
*/
#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...