제출 #788991

#제출 시각아이디문제언어결과실행 시간메모리
788991AlcabelAliens (IOI16_aliens)C++17
4 / 100
12 ms340 KiB
#include <bits/stdc++.h>
#ifndef LOCAL
#include "aliens.h"
#endif
using namespace std;
const long long inf = 1e13;
const int maxiters = 200;
 
struct Line {
    int a;
    long double b;
    Line() {}
    Line(int _a, long double _b) {
        a = _a, b = _b;
    }
    long double f(int x) {
        return a * 1ll * x + b;
    }
    ~Line() {}
};

const long double eps = 1e-6; 
int sign(long double x) {
    if (x > eps) { return 1; }
    if (x < eps) { return -1; }
    return 0;
}
 
long long intersect(const Line& A, const Line& B) {
    // x = (B.b - A.b) / (A.a - B.a)
    long double numer = B.b - A.b, denom = A.a - B.a;
    return ceill(numer / denom);
    /*int sn = sign(numer), sd = sign(denom);
    numer *= sn, denom *= sd;
    if (sn * sd < eps) {
        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);
    vector<pair<long double, int>> dp(n);
    vector<Line> lines;
    vector<long double> optX;
    vector<int> cntSegs;
    long double left = -inf, right = inf;
    long long ans = (segs.back().second - segs[0].first) * 1ll * (segs.back().second - segs[0].first);
    for (int iter = 0; iter < maxiters; ++iter) {
        long double mid = left + (right - left) / 2;
        lines = {};
        optX = {};
        cntSegs = {};
        dp[0] = {(segs[0].second - segs[0].first) * 1ll * (segs[0].second - segs[0].first) + mid, 1};
        for (int i = 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[i - 1].first - lenInter * 1ll * lenInter + segs[i].first * 1ll * segs[i].first);
            while (!lines.empty() && sign(intersect(lines.back(), l) - optX.back()) != 1) {
                optX.pop_back();
                lines.pop_back();
                cntSegs.pop_back();
            }
            if (!lines.empty()) {
                optX.emplace_back(intersect(lines.back(), l));
            } else {
                optX.emplace_back(-1);
            }
            lines.emplace_back(l);
            cntSegs.emplace_back(dp[i - 1].second);
            // 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[i] = {lines[ptr].f(segs[i].second) + segs[i].second * 1ll * segs[i].second + mid, cntSegs[ptr] + 1};
            if (sign((segs[i].second - segs[0].first) * 1ll * (segs[i].second - segs[0].first) + mid - dp[i].first) != 1) {
                dp[i] = {(segs[i].second - segs[0].first) * 1ll * (segs[i].second - segs[0].first) + mid, 1};
            }
        }
        if (dp[n - 1].second <= k) {
            right = mid;
            long long cur = floorl(dp.back().first - dp.back().second * mid);
            if (sign(dp.back().first - dp.back().second * mid - cur) == 1) {
                ++cur;
            }
            ans = min(ans, cur);
        } else {
            left = mid;
        }
        /*cerr << "g: " << g << ", subtracted:\n";
        for (int i = g - 1; i < n; ++i) {
            cerr << dp[layer ^ 1][i] - dp[layer][i] << ' ';
        }
        cerr << '\n';
        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...