제출 #290263

#제출 시각아이디문제언어결과실행 시간메모리
290263KastandaAliens (IOI16_aliens)C++11
100 / 100
498 ms12828 KiB
// M #include<bits/stdc++.h> #include "aliens.h" #define x first #define y second using namespace std; typedef long long ll; typedef long double ld; struct CHT { typedef pair < ld , ld > Line; deque < pair < ld , pair < Line , int > > > A; ld INF = 1e18; inline void Add(Line X, int i) { while (A.size() && Intersection(A.back().second.first, X) <= A.back().first) A.pop_back(); if (A.size()) A.push_back({Intersection(A.back().second.first, X), {X, i}}); else A.push_back({-INF, {X, i}}); } inline int GetMax(ld X) { while (A.size() > 1 && A[1].first <= X) A.pop_front(); return A[0].second.second; } inline ld Intersection(Line X, Line Y) { if (X.first == Y.first) return X.second <= Y.second ? -INF : INF; return (X.second - Y.second) / (Y.first - X.first); } }; const int N = 100005; int n, m, k, Cnt[N]; ll CutOff[N]; ld dp[N]; pair < int , int > A[N]; inline int Solve(ld md) { CHT C; auto Add = [&](int i){ C.Add(make_pair(2LL * (A[i + 1].y - 1), - dp[i] + CutOff[i] - (ll)(A[i + 1].y - 1) * (A[i + 1].y - 1)), i); }; auto GetValue = [&](int i, int j){ return (dp[j] - CutOff[j] + (ll)(A[i].x - A[j + 1].y + 1) * (A[i].x - A[j + 1].y + 1)); }; Add(0); for (int i = 1; i <= n; i ++) { int j = C.GetMax(A[i].x); Cnt[i] = Cnt[j] + 1; dp[i] = GetValue(i, j) + md; Add(i); } return Cnt[n]; } long long take_photos(int _n, int _m, int _k, vector < int > _R, vector < int > _C) { n = _n; m = _m; k = _k; for (int i = 0; i < n; i ++) A[i] = {_C[i], _R[i]}; for (int i = 0; i < n; i ++) if (A[i].x < A[i].y) swap(A[i].x, A[i].y); vector < int > MN(m, m); for (int i = 0; i < n; i ++) MN[A[i].x] = min(MN[A[i].x], A[i].y); n = 0; for (int i = m - 1; i >= 0; i --) if (MN[i] != m) if (!n || A[n].y > MN[i]) A[++ n] = make_pair(i, MN[i]); reverse(A + 1, A + n + 1); k = min(k, n); for (int i = 1; i < n; i ++) if (A[i].x >= A[i + 1].y) CutOff[i] = (ll)(A[i].x - A[i + 1].y + 1) * (A[i].x - A[i + 1].y + 1); // Phew .. ld le = 0, ri = 1e13, md; for (int __ = 0; __ <= 60; __ ++) { md = (le + ri) * 0.5; if (Solve(md) >= k) le = md; else ri = md; } Solve(le); return (ll)(dp[n] - k * le + 0.5); }
#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...