제출 #1280755

#제출 시각아이디문제언어결과실행 시간메모리
1280755PanndaBulldozer (JOI17_bulldozer)C++20
0 / 100
2 ms840 KiB
#include <bits/stdc++.h> using namespace std; template<class Info> struct SegmentTree { int n; vector<Info> info; SegmentTree() : n(0) {} SegmentTree(int n_, Info v_ = Info()) { init(n_, v_); } template<class T> SegmentTree(vector<T> init_) { init(init_); } void init(int n_, Info v_ = Info()) { init(vector<Info>(n_, v_)); } template<class T> void init(std::vector<T> init_) { n = init_.size(); info.assign(4 << std::__lg(n), Info()); std::function<void(int, int, int)> build = [&](int p, int l, int r) { if (r - l == 1) { info[p] = init_[l]; return; } int m = (l + r) / 2; build(2 * p, l, m); build(2 * p + 1, m, r); pull(p); }; build(1, 0, n); } void pull(int p) { info[p] = info[2 * p] + info[2 * p + 1]; } void modify(int p, int l, int r, int x, const Info &v) { if (r - l == 1) { info[p] = v; return; } int m = (l + r) / 2; if (x < m) { modify(2 * p, l, m, x, v); } else { modify(2 * p + 1, m, r, x, v); } pull(p); } void modify(int p, const Info &v) { modify(1, 0, n, p, v); } Info rangeQuery(int p, int l, int r, int x, int y) { if (l >= y || r <= x) { return Info(); } if (l >= x && r <= y) { return info[p]; } int m = (l + r) / 2; return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y); } Info rangeQuery(int l, int r) { return rangeQuery(1, 0, n, l, r); } template<class F> int findFirst(int p, int l, int r, int x, int y, F &&pred) { if (l >= y || r <= x) { return -1; } if (l >= x && r <= y && !pred(info[p])) { return -1; } if (r - l == 1) { return l; } int m = (l + r) / 2; int res = findFirst(2 * p, l, m, x, y, pred); if (res == -1) { res = findFirst(2 * p + 1, m, r, x, y, pred); } return res; } template<class F> int findFirst(int l, int r, F &&pred) { return findFirst(1, 0, n, l, r, pred); } template<class F> int findLast(int p, int l, int r, int x, int y, F &&pred) { if (l >= y || r <= x) { return -1; } if (l >= x && r <= y && !pred(info[p])) { return -1; } if (r - l == 1) { return l; } int m = (l + r) / 2; int res = findLast(2 * p + 1, m, r, x, y, pred); if (res == -1) { res = findLast(2 * p, l, m, x, y, pred); } return res; } template<class F> int findLast(int l, int r, F &&pred) { return findLast(1, 0, n, l, r, pred); } }; struct Info { long long mx = 0; long long pre = 0; long long suf = 0; long long sum = 0; Info() {} Info(long long x) { sum = x; mx = pre = suf = max(0LL, x); } Info operator+(const Info &b) { Info ret; ret.mx = max({mx, b.mx, suf + b.pre}); ret.pre = max(pre, sum + b.pre); ret.suf = max(b.suf, b.sum + suf); ret.sum = sum + b.sum; return ret; } }; #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x), end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair<int, int> pii; typedef vector<int> vi; struct point { int x, y; long long w; bool operator<(const point &other) const { return tie(x, y) < tie(other.x, other.y); } }; struct Line{ ll i, j, dx, dy; // dx >= 0 Line(int i, int j, const point &pi, const point &pj) : i(i), j(j), dx(pj.x-pi.x), dy(pj.y-pi.y) {} bool operator < (const Line &l) const { return make_tuple(dy*l.dx, i, j) < make_tuple(l.dy*dx, l.i, l.j); } bool operator == (const Line &l) const { return dy * l.dx == l.dy * dx; } }; void Bulldozer(vector<point> a, auto &&swapcb, auto &&updatecb){ // V.reserve(N*(N-1)/2) int n = a.size(); vector<int> p(n); sort(a.begin(), a.end()); iota(p.begin(), p.end(), 0); vector<Line> v; for(int i=0; i<n; i++) for(int j=i+1; j<n; j++) v.emplace_back(i, j, a[i], a[j]); sort(v.begin(), v.end()); for(int i=0, j=0; i<v.size(); i=j){ while(j < v.size() && v[i] == v[j]) j++; for(int k=i; k<j; k++){ int x = v[k].i, y = v[k].j; // point id, index -> Pos[id] swapcb(p[x], p[y]); swap(p[x], p[y]); } updatecb(); } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; map<array<int, 2>, long long> mp; for (int i = 0; i < n; i++) { int x, y, w; cin >> x >> y >> w; mp[{x, y}] += w; } vector<point> a; for (auto [xy, w] : mp) { auto [x, y] = xy; a.push_back({x, y, w}); } n = a.size(); vector<long long> v; for (auto [x, y, w] : a) { v.push_back(w); } SegmentTree<Info> seg(v); long long ans = 0; Bulldozer(a, [&](int i, int j) { int x = v[i]; int y = v[j]; seg.modify(i, y); seg.modify(j, x); swap(v[i], v[j]); }, [&]() { ans = max(ans, seg.rangeQuery(0, n).mx); }); cout << ans << '\n'; }
#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...