제출 #764667

#제출 시각아이디문제언어결과실행 시간메모리
764667mousebeaverAliens (IOI16_aliens)C++14
100 / 100
1055 ms8124 KiB
#include "aliens.h" #include <bits/stdc++.h> #define ll long long #define INF numeric_limits<ll>::max()/2 #define pll pair<ll, ll> using namespace std; ll cost(ll i, ll j, vector<pll>& a) { ll root = a[j-1].second - a[i-1].first+1; ll area = root*root; //Area of the necessary square to cover the given cells if(i > 1 && a[i-1].first <= a[i-2].second) { //Calculate the overlap with the previous square root = a[i-2].second-a[i-1].first+1; area -= root*root; } return area; } void calc(vector<vector<ll>>& dp, ll j, ll left, ll right, ll optl, ll optr, vector<pll>& a) { if(left > right) { return; } ll mid = (left+right)/2; ll opt = -1; for(ll b = optl; b <= min(optr, mid); b++) { ll val = dp[b-1][j-1]+cost(b, mid, a); if(val < dp[mid][j]) { dp[mid][j] = val; opt = b; } } dp[mid][j] = min(dp[mid][j], dp[mid][j-1]); calc(dp, j, left, mid-1, optl, opt, a); calc(dp, j, mid+1, right, opt, optr, a); } ll f(ll i, ll j, vector<ll>& dp, vector<pll>& a) //First index with j better as i { ll n = a.size(); if(dp[i-1]+cost(i, n, a) <= dp[j-1]+cost(j, n, a)) { return n+1; } ll left = j; ll right = n; while(left < right) { ll mid = (left+right)/2; if(dp[j-1]+cost(j, mid, a) < dp[i-1]+cost(i, mid, a)) { right = mid; } else { left = mid+1; } } return left; } void calcDP(vector<pll>& a, ll delt, ll& cnt, ll& val) { ll n = a.size(); vector<ll> dp(n+1, INF); vector<ll> counter(n+1, 0); dp[0] = 0; deque<pll> q = {{1, 1}}; //index of point, starting being the best for(ll i = 1; i <= n; i++) { pll t = q.front(); q.pop_front(); while(q.size() && q.front().second <= i) { t = q.front(); q.pop_front(); } dp[i] = dp[t.first-1]+cost(t.first, i, a)+delt; counter[i] = counter[t.first-1]+1; q.push_front(t); if(i == n) { break; } while(q.size() && f(q.back().first, i+1, dp, a) <= q.back().second) { q.pop_back(); } ll start = 1; if(q.size()) { start = f(q.back().first, i+1, dp, a); } q.push_back({i+1, start}); } val = dp[n]; cnt = counter[n]; } long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) { vector<pll> a(n); for(ll i = 0; i < n; i++) { a[i] = {r[i], c[i]}; if(c[i] < r[i]) //Mirror to diagonal or above { swap(a[i].first, a[i].second); } } sort(a.begin(), a.end()); vector<pll> b(0); for(ll i = 0; i < n; i++) { if((i == n-1 || a[i].first != a[i+1].first) && (b.empty() || a[i].second > b.back().second)) { b.push_back(a[i]); } } a = b; n = a.size(); k = min(k, n); if(false) { vector<vector<ll>> dp(n+1, vector<ll> (k+1, INF)); dp[0][0] = 0; for(ll i = 1; i <= n; i++) { for(ll j = 1; j <= k; j++) { dp[i][j] = dp[i][j-1]; for(ll b = 1; b <= i; b++) { ll val = dp[b-1][j-1]+cost(b, i, a); dp[i][j] = min(dp[i][j], val); } } } return dp[n][k]; } if(false) { vector<vector<ll>> dp(n+1, vector<ll> (k+1, INF)); dp[0][0] = 0; for(ll j = 1; j <= k; j++) { calc(dp, j, j, n, 1, n, a); } return dp[n][k]; } ll left = 0; ll right = (ll) m * (ll) m; ll val = 0; ll cnt; while(left < right) { ll mid = (left+right)/2; calcDP(a, mid, cnt, val); if(cnt > k) { left = mid+1; } else { right = mid; } } calcDP(a, left, cnt, val); return val-left*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...