Submission #498510

#TimeUsernameProblemLanguageResultExecution timeMemory
498510600MihneaBulldozer (JOI17_bulldozer)C++17
100 / 100
1965 ms197628 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct Point { ll x; ll y; ll value; }; struct R { int sgn; ll up; ll down; int i; int j; }; R get(ll x, ll y) { R sol; sol.sgn = +1; if (x < 0 && y < 0) { x *= -1; y *= -1; } if (x < 0 || y < 0) { sol.sgn = -1; } sol.up = abs(x); sol.down = abs(y); return sol; } bool operator < (R a, R b) { if (a.sgn != b.sgn) { return a.sgn < b.sgn; } if (a.sgn == -1) { swap(a, b); } return a.up * b.down < b.up * a.down; } bool initialCmp(Point a, Point b) { if (a.y == b.y) { return a.x < b.x; } return a.y < b.y; } const int N = 2000 + 7; int n; R panta[N][N]; Point points[N]; ll value[N]; void sneakyHack() { for (int i = 1; i <= n; i++) { swap(points[i].x, points[i].y); } } int ord[N]; int inv[N]; struct Node { ll sol; ll sum; ll pref; ll suf; }; Node operator + (Node a, Node b) { ll sol = max(max(a.sol, b.sol), a.suf + b.pref); ll sum = a.sum + b.sum; ll pref = max(a.pref, a.sum + b.pref); ll suf = max(b.suf, b.sum + a.suf); return {sol, sum, pref, suf}; } Node tree[4 * N]; void build(int v, int tl, int tr) { if (tl == tr) { tree[v] = {max(value[tl], 0LL), value[tl], max(value[tl], 0LL), max(value[tl], 0LL)}; } else { int tm = (tl + tr) / 2; build(2 * v, tl, tm); build(2 * v + 1, tm + 1, tr); tree[v] = tree[2 * v] + tree[2 * v + 1]; } } void upd(int v, int tl, int tr, int i) { if (tr < i || i < tl) { return; } if (tl == tr) { tree[v] = {max(value[tl], 0LL), value[tl], max(value[tl], 0LL), max(value[tl], 0LL)}; } else { int tm = (tl + tr) / 2; upd(2 * v, tl, tm, i); upd(2 * v + 1, tm + 1, tr, i); tree[v] = tree[2 * v] + tree[2 * v + 1]; } } int main() { bool isHome; isHome = true; isHome = false; if (isHome) { freopen ("input", "r", stdin); } else { ios::sync_with_stdio(0); cin.tie(0); } cin >> n; for (int i = 1; i <= n; i++) { cin >> points[i].x >> points[i].y >> points[i].value; } ll best = 0; for (int iteration = 1; iteration <= 2; iteration++) { sneakyHack(); sort(points + 1, points + n + 1, initialCmp); for (int i = 1; i <= n; i++) { ord[i] = i; inv[i] = i; for (int j = i + 1; j <= n; j++) { panta[i][j] = get(points[i].x - points[j].x, points[i].y - points[j].y); panta[i][j].i = i; panta[i][j].j = j; } value[i] = points[i].value; } vector<R> all; for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { if (points[i].y != points[j].y) { all.push_back(panta[i][j]); } } } build(1, 1, n); stable_sort(all.begin(), all.end()); /** second : 22 16 10 8 9 11 23 17 15 29 => 19 ------------------------------------------ second : 29 22 16 10 8 9 11 23 17 15 => 21 **/ best = max(best, tree[1].sol); /// all[it] < all[it + 1] int l = 0; while (l < (int) all.size()) { int r = l; while (r + 1 < (int) all.size() && !(all[r] < all[r + 1])) { r++; } for (int it = l; it <= r; it++) { int i = all[it].i; int j = all[it].j; int pos_i = inv[i]; int pos_j = inv[j]; swap(ord[pos_i], ord[pos_j]); inv[ord[pos_i]] = pos_i; inv[ord[pos_j]] = pos_j; swap(value[pos_i], value[pos_j]); upd(1, 1, n, pos_i); upd(1, 1, n, pos_j); } best = max(best, tree[1].sol); l = r + 1; } } cout << best << "\n"; return 0; }

Compilation message (stderr)

bulldozer.cpp: In function 'int main()':
bulldozer.cpp:118:13: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |     freopen ("input", "r", stdin);
      |     ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
#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...