이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |