제출 #138849

#제출 시각아이디문제언어결과실행 시간메모리
138849mosesmayerAliens (IOI16_aliens)C++17
4 / 100
4 ms2040 KiB
#include "aliens.h" #include <bits/stdc++.h> #define fi first #define se second #define pb push_back using namespace std; typedef long long LL; typedef pair<int,int> pii; struct Line{ LL m, c; Line(LL m = 0, LL c = 0): m(m), c(c){} LL get(LL x){return m * x + c;} }; struct ConvexHull{ int sz, B; Line *hull; int *idx; ConvexHull(int n): sz(0), B(0){ hull = new Line[++n]; idx = new int[n]; } bool is_bad(int curr, int prev, int next){ Line c = hull[curr], p = hull[prev], n = hull[next]; return (c.c - n.c) * (c.m - p.m) <= (p.c - c.c) * (n.m - c.m); } void add_line(LL m, LL c, int id){ hull[sz++] = Line(m, c); idx[sz] = id; while (sz > 2 && is_bad(sz-2, sz-3, sz-1)){ hull[sz-2] = hull[sz-1]; idx[sz-2] = idx[sz-1]; sz--; } B = min(B, sz - 1); } pair<LL, int> query(LL x){ while (B < sz - 1 && hull[B].get(x) >= hull[B+1].get(x)) B++; return make_pair(hull[B].get(x), idx[B]); } }; const LL LINF = 1e18; const int MX = 1e5; int n, m, k; vector<pii> ori; LL L[MX + 5], R[MX + 5], nx[MX + 5]; LL dp[MX + 5]; int cnt[MX + 5]; ConvexHull ch(MX + 5); bool cmp(pii a, pii b){ return a.fi != b.fi ? a.fi < b.fi : a.se > b.se; } /* dp[k][n] = min(dp[k-1][n], min{j<=n} (dp[k-1][j-1] + (L[j]^2-2L[j]) + max(0,R[j-1]-L[j]+1)^2 - 2L[j]•R[n]) + R[n]^2 + 2R[n] + 1; ( c1 ) ( c2 ) ( m ) ( x ) ( extra ) */ int check(LL C){ ch.sz = 0; ch.B = 0; for (int j = 1; j <= n; j++){ ch.add_line(-2LL * L[j], dp[j-1] + L[j] * (L[j] - 2) - nx[j] * nx[j], j); pair<LL, int> res = ch.query(R[j]); dp[j] = res.first + R[j] * R[j] + 2LL * R[j] + 1 + C; cnt[j] = cnt[res.second] + 1; // cout << "J/" << j << " : " << dp[j] << ' ' << cnt[j] << '\n'; } // cout << "Checking C : " << C << " with result " << dp[n] << ' ' << cnt[n] << '\n'; return cnt[n]; } long long take_photos(int N, int M, int K, std::vector<int> r, std::vector<int> c) { n = N, m = M, k = K; for (int i = 0; i < n; i++){ ori.emplace_back(r[i], c[i]); if (ori.back().fi > ori.back().se) swap(ori.back().fi, ori.back().se); } sort(ori.begin(), ori.end()); int idx = 0; for (int i = 0; i < n; i++){ if (idx && L[idx] <= ori[i].fi && R[idx] >= ori[i].se) continue; while (idx && ori[i].fi <= L[idx] && ori[i].se >= R[idx]) idx--; idx++; tie(L[idx], R[idx]) = ori[i]; } n = idx; // for (int i = 1; i <= n; i++) printf("(%d, %d)%c", L[i], R[i], " \n"[i==n]); L[0] = R[0] = -1; for (int i = 1; i <= n; i++) nx[i] = max(0LL, R[i-1] - L[i] + 1); // for (int i = 1; i <= n; i++) printf("%lld%c", nx[i], " \n"[i==n]); LL lo = 0, hi = 1e18, md, ans = 0; while (lo <= hi){ md = (lo + hi) >> 1; if (check(md) >= k){ ans = md; lo = md + 1; } else hi = md - 1; } int kk = check(ans); // cout << ans << ' ' << kk << '\n'; return dp[n] - ans * kk; }
#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...