제출 #209559

#제출 시각아이디문제언어결과실행 시간메모리
209559oolimryAliens (IOI16_aliens)C++14
100 / 100
243 ms8804 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; typedef pair<long long, long long> ii; vector<ii> allRanges; ///all the ranges vector<ii> arr; ///non-overalping ranges we need to consider inline long long square(long long x){ return x * x; } bool comp(ii a, ii b){ if(a.first == b.first) return a.second > b.second; return a.first < b.first; } struct Line{ long long m, c, taken; }; inline long double intersect(Line a, Line b){ return (long double) (b.c - a.c) / (long double) (a.m - b.m); } struct ConvexHull{ Line hull[100005]; int l = 0, r = -1; void reset(){ l = 0, r = -1; } ///take as many if tie by cost bool redundantBack(){ if(r - l < 2) return false; if(abs(intersect(hull[r],hull[r-1]) - intersect(hull[r-2],hull[r])) <= 0.00000001) return hull[r].taken > hull[r-1].taken; return intersect(hull[r-1],hull[r-2]) > intersect(hull[r],hull[r-2]); } ///return the best value, and also how many ranges taken ii getBest(long long k){ while(r - l > 0 && intersect(hull[l],hull[l+1]) < (long double) k) l++; long long ans = (hull[l].m * k + hull[l].c); return ii(ans, hull[l].taken); } void addLine(long long m, long long c, long long taken){ if(r - l < 0 || hull[r].m > m) hull[++r] = {m,c,taken}; else if(hull[r].c > c) hull[r] = {m,c,taken}; else if(hull[r].c == c && hull[r].taken < taken) hull[r] = {m,c,taken}; while(redundantBack()){ hull[r-1] = hull[r]; r--; } } } ch; inline ii monge(long long cost){ ch.reset(); ch.addLine(-2LL * arr[0].first, square(arr[0].first), 1); ///option for taking from the start ii dp; ///ii(bestAns, taken) for(int i = 0;i < (int) arr.size();i++){ ii x = arr[i]; dp = ch.getBest(x.second); dp.first += square(x.second); dp.first += cost; ///add a cost for taking a range if(i != (int) arr.size() - 1){ long long gradient = -2 * arr[i+1].first; long long yIntercept = dp.first - square(max(0LL, arr[i].second - arr[i+1].first)) + square(arr[i+1].first); ch.addLine(gradient, yIntercept, dp.second + 1); } } return dp; } long long take_photos(int n, int m, int K, vector<int> L, vector<int> R) { for(int i = 0;i < n;i++){ if(L[i] > R[i]) swap(L[i], R[i]); allRanges.push_back(ii(L[i],R[i])); } ///sort the ranges sort(allRanges.begin(),allRanges.end(),comp); ///remove all ranges which are fully contained in another int maxR = -1; for(ii r : allRanges){ if(r.second > maxR){ maxR = r.second; arr.push_back(ii(r.first,r.second+1)); } } if(arr.size() == 1){ return square(arr[0].second - arr[0].first); } long long low = -1; long long high = square(m); while(true){ if(low == high - 1) break; long long s = (low + high) / 2LL; if(monge(s).second <= K) high = s; else low = s; } ii ansHigh = monge(high); long long ans = ansHigh.first - K * high; return ans; }
#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...