제출 #1166659

#제출 시각아이디문제언어결과실행 시간메모리
1166659NxmkxingAliens (IOI16_aliens)C++20
100 / 100
181 ms41416 KiB
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using pll = pair<long long, long long>;
const ll inf = 1e18;

const int N = 1e5 + 10;
const int M = 1e6 + 10;
ll n, f[N], mx, minR[M], bestR[M], mxC[M], bestC[M], x[N], y[N];
vector<pll> v, a;
pll dp[N];

struct CHT {
    struct line {
        ll m, c, cnt;
        ll eval(ll x) { return m * x + c; }
    };
    double intersectX(line a, line b) { return (a.c - b.c) / (b.m - a.m); }
    deque<line> dq;
    void add(ll m, ll c, ll cnt) {
        line l = {m, c, cnt};
        while (dq.size() > 1 && intersectX(l, dq[0]) <= intersectX(dq[0], dq[1])) dq.pop_front();
        dq.push_front(l);
    }
    pll get(ll x) {
        while (dq.size() > 1 && dq.back().eval(x) > dq.end()[-2].eval(x)) dq.pop_back();
        return {dq.back().eval(x), dq.back().cnt};
    }
};

pll solve(ll lambda) {
    CHT cht;
    for (int i = 1; i <= n; i++) dp[i] = {inf, 0};
    for (int i = 1; i <= n; i++) {
        ll c = x[i] * x[i] + dp[i-1].first;
        if (i > 1 && y[i-1] >= x[i]) c -= (y[i-1] - x[i]) * (y[i-1] - x[i]);
        cht.add(-2 * x[i], c, dp[i-1].second);
        auto [v, cnt] = cht.get(y[i]);
        dp[i] = {y[i] * y[i] + lambda + v, cnt + 1};
    }
    return dp[n];
}

ll take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
    for (int i = 0; i < n; i++) if (r[i] > c[i]) swap(r[i], c[i]);
    for (int i = 0; i < n; i++) v.push_back({r[i], c[i]});
    sort(v.begin(), v.end());
    v.resize(unique(v.begin(), v.end()) - v.begin());
    n = v.size();
    //for (auto [x, y] : v) cout << x << " " << y << "\n";
    for (int i = 0; i < m; i++) minR[i] = m;
    for (int i = 0; i < m; i++) mxC[i] = bestR[i] = bestC[i] = -1;
    for (int i = 0; i < n; i++) {
        auto [x, y] = v[i];
        if (minR[y] > x) minR[y] = x, bestR[y] = i;
        if (mxC[x] < y) mxC[x] = y, bestC[x] = i;
    }
    //for (int i = 0; i < m; i++) cout << bestR[i] << " "; cout << "\n";
    //for (int i = 0; i < m; i++) cout << bestC[i] << " "; cout << "\n";
    for (int i = 0; i < m; i++) if (bestR[i] != -1) f[bestR[i]]++;
    for (int i = 0; i < m; i++) if (bestC[i] != -1) f[bestC[i]]++;
    //for (int i = 0; i < n; i++) cout << f[i] << " "; cout << "\n";
    for (int i = 0; i < n; i++) if (f[i] == 2) a.push_back({v[i].first, v[i].second});
    //for (auto [x, y] : a) cout << x << " " << y << "\n";
    sort(a.begin(), a.end());
    n = a.size();
    mx = -1;
    for (int i = 0; i < n; i++) f[i] = 0;
    for (int i = 0; i < n; i++) {
        auto [x, y] = a[i];
        if (mx < y) mx = y, f[i] = 1;
    }
    v.clear();
    for (int i = 0; i < n; i++) if (f[i]) v.push_back({a[i].first, a[i].second});
    n = v.size();
    ::n = n;
    for (int i = 1; i <= n; i++) x[i] = v[i-1].first, y[i] = v[i-1].second + 1;
    //cout << "\n" << n << "\n"; for (int i = 1; i <= n; i++) cout << x[i] << " " << y[i] << "\n";
    // solve
    ll b = 0, e = 1e18;
    while (b < e) {
        ll mid = (b + e) / 2;
        if (solve(mid).second > k) b = mid + 1;
        else e = mid;
    }
    //for (int i = 1; i <= n; i++) cout << dp[i] << " ";
    return solve(b).first - b * k;
}

컴파일 시 표준 에러 (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...