제출 #107211

#제출 시각아이디문제언어결과실행 시간메모리
107211tictaccatAliens (IOI16_aliens)C++14
60 / 100
2125 ms777048 KiB
#include "aliens.h"
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

const ll INF = (ll)1e18;

ll ccw (pair<ll,ll> p1, pair<ll,ll> p2, pair<ll,ll> p3) {
    return (p2.first-p1.first)*(p3.second-p2.second) - (p2.second-p1.second)*(p3.first-p2.first);
}

struct Hull {
    vector<pair<ll,ll>> hull; ll p = 0;
    void insert(pair<ll,ll> p) { //points inserted with increasing x
       // if (hull.size()) assert(p.first >= hull.back().first);
        while (hull.size() >= 2 && ccw(hull[hull.size()-2],hull.back(),p) < 0) hull.pop_back();
        hull.push_back(p); 
    }
    ll query(ll k) { //minimise y-kx
       while (p < hull.size()-1 && -k*hull[p].first + hull[p].second > -k*hull[p+1].first + hull[p+1].second) p++;
        return -k*hull[p].first + hull[p].second;
        // ll low = INF;
        // for (auto p: hull) low = min(low,-k*p.first+p.second);
        // return low; 
    }
};

ll take_photos(int n, int m, int k, vector<int> ri, vector<int> ci) {

    vector<pair<ll,ll>> points;
    for (int i = 0; i < n; i++) points.push_back(make_pair(max(ci[i],ri[i]),min(ri[i],ci[i])));
    sort(points.begin(),points.end());

    vector<ll> r,c; //such that r_i < r_j, c_i < c_j

    for (int i = 0; i < n; i++) {
        while (r.size() > 0 && points[i].second <= r.back()) {
            r.pop_back(); c.pop_back();
        }
        r.push_back(points[i].second); c.push_back(points[i].first);
    }

    n = r.size();

   // for (int i = 0; i < n; i++) cout << r[i] << " " << c[i] << "\n";

    vector<vector<ll>> dp(k+1, vector<ll> (n+1,INF)); //dp[k][i] = min squares covered over the first i points, using k segments
    vector<Hull> hulls(k+1);

    for (int u = 0; u <= k; u++) {
        dp[u][0] = 0;
        hulls[u].insert(make_pair(2*r[0],r[0]*r[0]-2*r[0]));
    }

    for (int i = 1; i <= n; i++) {
        for (int u = 1; u <= k; u++) {
            dp[u][i] = (c[i-1]+1)*(c[i-1]+1) + hulls[u-1].query(c[i-1]);
            ll overlap;
            if (c[i-1] < r[i]) overlap = 0LL;
            else overlap = (c[i-1]-r[i]+1)*(c[i-1]-r[i]+1);           
            if (i < n) hulls[u].insert(make_pair(2*r[i],dp[u][i] + r[i]*r[i]-2*r[i]-overlap));
        }
    }
   
   return dp[k][n];
}

// int main() {

//     Hull test;

//     test.insert({3,4});

//     test.insert({3,4});

//     test.insert({5,1});

//     cout << test.query(0) << "\n";


// }

컴파일 시 표준 에러 (stderr) 메시지

aliens.cpp: In member function 'll Hull::query(ll)':
aliens.cpp:21:17: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
        while (p < hull.size()-1 && -k*hull[p].first + hull[p].second > -k*hull[p+1].first + hull[p+1].second) p++;
               ~~^~~~~~~~~~~~~~~
#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...