# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1017277 | khanhphucscratch | Aliens (IOI16_aliens) | C++14 | 0 ms | 0 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
#include "aliens.h"
#define int long long
using namespace std;
struct CHT
{
vector<pair<int, int>> line;
vector<double> hull;
double intersection(pair<int, int> x, pair<int, int> y)
{
return (double)(x.second - y.second) / (y.first - x.first);
}
void addline(pair<int, int> x)
{
while(hull.size() > 0 && intersection(x, line[line.size()-1]) <= hull[hull.size()-1]){
hull.pop_back(); line.pop_back();
}
if(line.size() > 0) hull.push_back(intersection(line[line.size()-1], x));
line.push_back(x);
}
int bestval(int x)
{
if(line.size() == 0) return 1e15;
int place = lower_bound(hull.begin(), hull.end(), x) - hull.begin();
return line[place].first*x+line[place].second;
}
};
CHT st[1005];
int dp[1005][505], last[1005];
inline bool cmp(pair<int, int> x, pair<int, int> y)
{
return x.second < y.second || (x.second == y.second && x.first > y.first);
}
int take_photos(int n, int m, int k, vector<int> r, vector<int> c)
{
//Transform to segments
vector<pair<int, int>> segment;
for(int i = 0; i < n; i++){
if(r[i] <= c[i]) segment.push_back({r[i], c[i]+1});
else segment.push_back({c[i], r[i]+1});
}
//Eliminate unnecessary segments
sort(segment.begin(), segment.end(), cmp);
vector<pair<int, int>> sus;
for(pair<int, int> i : segment){
if(sus.size() > 0 && sus[sus.size()-1].first >= i.first && sus[sus.size()-1].second <= i.second){
sus.pop_back();
}
sus.push_back(i);
}
memset(last, -1, sizeof(last));
for(pair<int, int> i : sus){
last[i.second] = i.first;
}
//O(mk log n) dp
int lastplace = -1;
st[0].addline({0, 0});
for(int i = 0; i <= m; i++){
for(int j = 0; j <= k; j++) if(last[i] > -1){
pair<int, int> newline = make_pair(-2*last[i], last[i]*last[i]);
if(lastplace > -1) newline.second += dp[lastplace][j];
st[j].addline(newline);
}
for(int j = 0; j <= k; j++){
if(last[i] == -1) dp[i][j] = dp[i-1][j];
else{
//cout<<st[0].bestval(i)<<endl;
if(j > 0) dp[i][j] = i*i + st[j-1].bestval(i);
else dp[i][j] = 1e15;
}
//cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
if(last[i] > -1) lastplace = i;
}
int ans = 1e18;
for(int i = 0; i <= k; i++) ans = min(ans, dp[m][i]);
return ans;
}
/*signed main()
{
int x[2] = {1, 4}, y[2] = {4, 1};
cout<<take_photos(2, 6, 2, x, y);
}*/