Submission #224740

#TimeUsernameProblemLanguageResultExecution timeMemory
224740BruteforcemanBulldozer (JOI17_bulldozer)C++11
100 / 100
1835 ms79448 KiB
#include <bits/stdc++.h> using namespace std; using pii = pair <int, int>; const int maxn = 2005; struct point { long long x, y, w; point () {} point (long long x, long long y) : x(x), y(y) {} point operator - (point p) { return point(x - p.x, y - p.y); } point operator + (point p) { return point(x + p.x, y + p.y); } point normalize() { long long d = __gcd(abs(x), abs(y)); if(d == 0) return *this; else return point(x / d, y / d); } } a[maxn]; long long dot(point p, point q) { return p.x*q.x + p.y*q.y; } long long cross(point p, point q) { return p.x*q.y - q.x*p.y; } bool operator < (point p, point q) { return cross(p, q) > 0; } long long dist(point p) { return dot(p, p); } bool vis[maxn]; int n; int cost[maxn]; int pos[maxn], c[maxn]; struct data { long long sum, opt, pre, suf; } t[maxn * 4]; struct info { point p; int i, j; info (point p, int i, int j) : p(p), i(i), j(j) {} info () {} bool operator < (info x) const { if(!cross(p, x.p)) { return dist(a[i] - a[j]) > dist(a[x.i] - a[x.j]); } return p < x.p; } }; data merge(data p, data q) { data x; x.sum = p.sum + q.sum; x.pre = max(p.pre, p.sum + q.pre); x.suf = max(q.suf, q.sum + p.suf); x.opt = max(p.opt, q.opt); x.opt = max(x.opt, p.suf + q.pre); return x; } void update(int x, int val, int c = 1, int b = 1, int e = n) { if(b == e) { t[c].sum = val; t[c].pre = t[c].suf = t[c].opt = max(0, val); return ; } int m = (b + e) >> 1; int l = c << 1; int r = l + 1; if(x <= m) update(x, val, l, b, m); else update(x, val, r, m + 1, e); t[c] = merge(t[l], t[r]); } long long maxSubarray() { return t[1].opt; } int main() { ios_base :: sync_with_stdio (false); cin.tie(0); cin >> n; long long ans = 0; for(int i = 1; i <= n; i++) { cin >> a[i].x >> a[i].y >> a[i].w; ans = max(ans, a[i].w); } sort(a + 1, a + n + 1, [&] (point p, point q) { return make_pair(p.y, p.x) < make_pair(q.y, q.x); }); vector <info> can; for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) { point p = a[j] - a[i]; p = p.normalize(); can.emplace_back(p, i, j); } } for(int i = 1; i <= n; i++) { pos[i] = i; c[i] = i; cost[i] = a[i].w; update(i, cost[i]); } sort(can.begin(), can.end()); int now = 0; while(now < can.size()) { vector <pair <int, int>> v; do { v.emplace_back(can[now].i, can[now].j); ++now; } while (now < can.size() && cross(can[now - 1].p, can[now].p) == 0); vector <pii> affected; for(auto j : v) { if(vis[pos[j.first]]) continue; for(int k = pos[j.first]; k <= pos[j.second]; k++) { vis[k] = true; } affected.emplace_back(pos[j.first], pos[j.second]); } ans = max(ans, maxSubarray()); for(auto j : affected) { reverse(c + j.first, c + j.second + 1); for(int k = j.first; k <= j.second; k++) { vis[k] = false; pos[c[k]] = k; cost[k] = a[c[k]].w; update(k, cost[k]); } } } cout << ans << endl; return 0; }

Compilation message (stderr)

bulldozer.cpp: In function 'int main()':
bulldozer.cpp:103:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while(now < can.size()) {
         ~~~~^~~~~~~~~~~~
bulldozer.cpp:108:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     } while (now < can.size() && cross(can[now - 1].p, can[now].p) == 0);
              ~~~~^~~~~~~~~~~~
#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...