Submission #632840

#TimeUsernameProblemLanguageResultExecution timeMemory
632840rainliofficialAliens (IOI16_aliens)C++17
0 / 100
1 ms340 KiB
#include "aliens.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll, ll> pii; template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; } template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } #define sz(x) (int)x.size() const int MAXN = 2e5+5; const ll INF = 1e18; void __print(int x) {cerr << x;} void __print(long x) {cerr << x;} void __print(long long x) {cerr << x;} void __print(unsigned x) {cerr << x;} void __print(unsigned long x) {cerr << x;} void __print(unsigned long long x) {cerr << x;} void __print(float x) {cerr << x;} void __print(double x) {cerr << x;} void __print(long double x) {cerr << x;} void __print(char x) {cerr << '\'' << x << '\'';} void __print(const char *x) {cerr << '\"' << x << '\"';} void __print(const string &x) {cerr << '\"' << x << '\"';} void __print(bool x) {cerr << (x ? "true" : "false");} template<typename T, typename V> void __print(const pair<T, V> &x); template<typename T> void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i); cerr << "}";} template<typename T, typename V> void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';} void _print() {cerr << "]\n";} template <typename T, typename... V> void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);} #ifdef DEBUG #define dbg(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << endl; #else #define dbg(x...) #endif struct Point{ ll r, c, id, cnt; bool operator<(const Point& o) const{ if (r != o.r){ return r < o.r; } return c < o.c; } }; bool byr(const Point& a, const Point& b){ return a.r != b.r ? a.r < b.r : a.c > b.c; // sort by smaller row, then by greater col } bool byc(const Point& a, const Point& b){ return a.c != b.c ? a.c < b.c : a.r > b.r; // smaller col, smaller row } ll sq(ll x){ return x*x; } ll get(pii a, int c){ return a.first * c + a.second; } double intersectX(pii a, pii b){ return (double)(b.second - a.second)/(a.first - b.first); // (b2 - b1)/(m1 - m2) } /* ll subtask5(int n, int k, vector<Point>& arr){ vector<vector<ll>> dp(n+1, vector<ll>(k+1, INF)); // dp[i][j] = max cover up to ith point after taking j pictures for (int i=0; i<=k; i++) dp[0][i] = 0; vector<deque<pii>> lines(k+1); vector<int> pj(k+1, 1); for (int i=1; i<=n; i++){ for (int j=1; j<=k; j++){ ll overlap = i > 1 && arr[i-2].c >= arr[i-1].r ? sq(arr[i-2].c - arr[i-1].r + 1) : 0; pii cur = {-2*(arr[i-1].r - 1), sq(arr[i-1].r - 1) + dp[i-1][j-1] - overlap}; while (sz(lines[j]) > 1 && intersectX(cur, lines[j][sz(lines[j])-2]) < intersectX(lines[j].back(), lines[j][sz(lines[j])-2])){ lines[j].pop_back(); } lines[j].push_back(cur); if (j > 1 && !lines[j].empty()){ while (sz(lines[j]) > 1 && get(lines[j].front(), arr[i-1].c) >= get(lines[j][1], arr[i-1].c)){ lines[j].pop_front(); } dp[i][j] = sq(arr[i-1].c) + get(lines[j].front(), arr[i-1].c); }else{ // take all points before in 1 single picture dp[i][j] = sq(arr[i-1].c - arr[0].r + 1); } // for (int ip=1; ip<=i; ip++){ // ll area = sq(arr[i-1].c - arr[ip-1].r + 1); // overlap = ip > 1 && arr[ip-2].c >= arr[ip-1].r ? sq(arr[ip-2].c - arr[ip-1].r + 1) : 0; // if (dp[i][j] > dp[ip-1][j-1] + area - overlap){ // dbg(dp[i][j]); // } // } } } // for (int i=0; i<=n; i++){ // for (int j=0; j<=k; j++){ // cout << dp[i][j] << " "; // } // cout << "\n"; // } } */ pii solve(ll penalty, vector<Point>& arr, int n, int k){ vector<pii> dp(n+1); // dp[i] = min area needed with penalty to cover the first i pictures deque<pair<pii, ll>> lines; for (int i=1; i<=n; i++){ ll overlap = i > 1 && arr[i-2].c >= arr[i-1].r ? sq(arr[i-2].c - arr[i-1].r + 1) : 0; pii cur = {-2*(arr[i-1].r - 1), sq(arr[i-1].r - 1) + dp[i-1].first - overlap + penalty}; while (sz(lines) > 1 && intersectX(cur, lines[sz(lines)-2].first) < intersectX(lines.back().first, lines[sz(lines)-2].first)){ lines.pop_back(); } lines.push_back({cur, dp[i-1].second + 1}); while (sz(lines) > 1 && get(lines.front().first, arr[i-1].c) >= get(lines[1].first, arr[i-1].c)){ lines.pop_front(); } dp[i] = {sq(arr[i-1].c) + get(lines.front().first, arr[i-1].c), lines.front().second}; } return dp[n]; } long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) { // reflect the points under the diag vector<Point> arr; int tot = 0; set<Point> allPoints; for (int i=0; i<n; i++){ if (r[i] > c[i]){ swap(r[i], c[i]); } Point cur = {r[i], c[i], tot, 1}; auto it = allPoints.find(cur); if (it != allPoints.end()){ arr[(*it).id].cnt++; }else{ arr.push_back(cur); allPoints.insert(cur); tot++; } } n = tot; sort(arr.begin(), arr.end(), byr); set<Point, decltype(&byc)> seen(&byc); for (int i=0; i<n; i++){ auto it = seen.lower_bound(arr[i]); if (it == seen.end()){ seen.insert(arr[i]); }else{ // Point upd = *it; // upd.cnt++; // seen.erase(it); // seen.insert(upd); } } arr.clear(); for (Point x : seen){ // cout << x.r << " " << x.c << " " << x.id << " " << x.cnt << "\n"; arr.push_back(x); } n = sz(arr); ll low = 0, high = 1e12; while (high - low > 1){ ll mid = (low + high)/2; if (solve(mid, arr, n, k).second < k){ // we can lower the price/penalty per photo high = mid; }else{ low = mid; } } // run dp pii ans = solve(low, arr, n, k); assert(ans.second >= k); return ans.first - k * low; }
#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...