Submission #135863

#TimeUsernameProblemLanguageResultExecution timeMemory
135863KastandaAliens (IOI16_aliens)C++11
100 / 100
800 ms17196 KiB
// ItnoE #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef double ld; struct CHT { typedef pair < ld , ld > Line; vector < pair < ld , pair < Line , ll > > > A; ld INF = (ld)1e18; inline void Clear() { A.clear(); } inline void Add(Line X, ll id) { 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, id}}); else A.push_back({-INF, {X, id}}); } inline pair < ld , ll > GetMax(ld X) { int lb = upper_bound(A.begin(), A.end(), pair < ld , pair < Line , ll > > {X, {{INF, INF}, -1}}) - A.begin() - 1; return (make_pair(A[lb].second.first.first * X + A[lb].second.first.second, A[lb].second.second)); } inline ld Intersection(Line X, Line Y) { if (X.first == Y.first && X.second <= Y.second) return (-INF); if (X.first == Y.first) return (INF); return ((X.second - Y.second) / (Y.first - X.first));// + ((X.second - Y.second) % (Y.first - X.first) > 0); } }; const int N = 100005, MXM = 1e6 + 10; int n, m, A[N], B[N], F[N], MN[MXM]; pair < ld , ll > dp[N]; inline ld SQR(ld a) {return (a * a);} inline pair < ld , ll > Solve(ld md) { CHT C; dp[0] = {0, 0}; for (int i = 1; i <= n; i ++) { ld vl = dp[i - 1].first + SQR(F[i]); if (i > 1 && B[i - 1] > F[i]) vl -= SQR(B[i - 1] - F[i]); C.Add({F[i], - vl}, i); auto tt = C.GetMax(2 * B[i]); tt.first *= -1; dp[i].first = tt.first + SQR(B[i]) + md; dp[i].second = dp[tt.second - 1].second + 1; } return (dp[n]); } int64_t take_photos(int q, int mm, int k, vector < int > RG, vector < int > CG) { m = mm; memset(MN, 63, sizeof(MN)); for (int i = 0; i < q; i ++) { if (RG[i] > CG[i]) swap(RG[i], CG[i]); MN[CG[i]] = min(MN[CG[i]], RG[i]); } for (int i = 0; i < m; i ++) if (MN[i] <= i) { int b = i, a = i - MN[i] + 1; while (n && B[n] - A[n] >= b - a) n --; n ++; B[n] = b; A[n] = a; F[n] = B[n] - A[n]; } ld le = 0, ri = (ll)m * m + 1, md; k = min(k, n); for (int _ = 0; _ <= 70; _ ++) { md = (le + ri) / 2; auto X = Solve(md); if (X.second <= k) ri = md; else le = md; } ld res = Solve(ri).first - ri * k; ll ret = floor(res + 0.12); return (ret); }
#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...