Submission #446873

#TimeUsernameProblemLanguageResultExecution timeMemory
446873flappybirdBulldozer (JOI17_bulldozer)C++14
100 / 100
1985 ms33584 KiB
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,fma")
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
#define MAX 101010
#define ln '\n'
struct Point {
	ll x, y;
	ll c;
	Point() :x(0), y(0) {}
	Point(ll x, ll y) :x(x), y(y) {}
	Point(ll x, ll y, ll c) :x(x), y(y), c(c) {}
};
bool operator<(const Point& p1, const Point& p2) {
	if (p1.x == p2.x) return p1.y < p2.y;
	return p1.x < p2.x;
}
bool operator==(const Point& p1, const Point& p2) {
	return p1.x == p2.x && p1.y == p2.y;
}
struct Node {
	ll lmx, rmx;
	ll sum, mx;
	Node(ll lmx, ll rmx, ll sum, ll mx) :lmx(lmx), rmx(rmx), sum(sum), mx(mx) {}
	Node() {
		lmx = rmx = mx = sum = 0;
	}
};
Node operator+(const Node& n1, const Node& n2) {
	Node ret;
	ret.lmx = max(n1.lmx, n1.sum + n2.lmx);
	ret.rmx = max(n2.rmx, n2.sum + n1.rmx);
	ret.sum = n1.sum + n2.sum;
	ret.mx = max(max(n1.mx, n2.mx), n1.rmx + n2.lmx);
	return ret;
}
struct segtree {
	vector<Node> tree;
	vector<ll> l, r;
	ll N, s;
	void init(ll x = 1) {
		if (x >= s) {
			l[x] = r[x] = x - s;
			return;
		}
		init(x * 2);
		init(x * 2 + 1);
		l[x] = l[x * 2];
		r[x] = r[x * 2 + 1];
		tree[x] = tree[x * 2] + tree[x * 2 + 1];
	}
	void update(ll x, ll v) {
		x += s;
		tree[x]= Node(max(0LL, v), max(0LL, v), v, max(0LL, v));
		x /= 2;
		while (x) {
			tree[x] = tree[x * 2] + tree[x * 2 + 1];
			x /= 2;
		}
	}
	ll maxall() {
		return tree[1].mx;
	}
	segtree(const vector<ll>& v) {
		N = v.size();
		s = 1LL << (ll)ceil(log2(N));
		l.resize(2 * s + 1);
		r.resize(2 * s + 1);
		tree.resize(2 * s + 1);
		ll i;
		for (i = 0; i < N; i++) tree[i + s] = Node(max(0LL, v[i]), max(0LL, v[i]), v[i], max(0LL, v[i]));
		init();
	}
	segtree() {}
};
vector<Point> point;
vector<pll> v;
vector<ll> val;
segtree seg;
bool cmp(const pll &p1, const pll &p2) {
	if ((point[p1.first].y - point[p1.second].y) * (point[p2.first].x - point[p2.second].x) == (point[p2.first].y - point[p2.second].y) * (point[p1.first].x - point[p1.second].x)) {
		if (point[p1.first] == point[p2.first]) return point[p1.second] < point[p2.second];
		return point[p1.first] < point[p2.first];
	}
	if (point[p1.first].y == point[p1.second].y) return (point[p2.first].y - point[p2.second].y) * (point[p2.first].x - point[p2.second].x) > 0;
	if (point[p2.first].y == point[p2.second].y) return (point[p1.first].y - point[p1.second].y) * (point[p1.first].x - point[p1.second].x) < 0;
	return (point[p1.first].y - point[p1.second].y) * (point[p2.first].x - point[p2.second].x) < (point[p2.first].y - point[p2.second].y) * (point[p1.first].x - point[p1.second].x);
}
bool eq(const pll& p1, const pll& p2) {
	return (point[p1.first].y - point[p1.second].y) * (point[p2.first].x - point[p2.second].x) == (point[p2.first].y - point[p2.second].y) * (point[p1.first].x - point[p1.second].x);
}
ll f(ll x) {
	if (!x) return 0;
	if (x > 0) return 1;
	else return -1;
}
ll ccw(Point p1, Point p2, Point p3) {
	return f((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y));
}
ll N;
ll calc() {
	ll i, j;
	if (N == 1) {
		val[0] = max(val[0], 0LL);
		return val[0];
	}
	v.clear();
	for (i = 0; i < N; i++) {
		for (j = i + 1; j < N; j++) {
			if (point[i].x != point[j].x) {
				if (point[i].x < point[j].x) v.push_back({ i, j });
				else v.push_back({ j, i });
			}
		}
	}
	if (v.empty()) return 0;
	sort(v.begin(), v.end(), cmp);
	Point p1, p2;
	p1 = point[v[0].second];
	p2 = point[v[0].first];
	vector<ll> ord, rev;
	ord.resize(N);
	rev.resize(N);
	for (i = 0; i < N; i++) ord[i] = i;
	ll a, b, c;
	a = (p2.y - p1.y);
	b = (p2.x - p1.x);
	c = (p2.x * p1.y - p1.x * p2.y);
	for (i = 0; i < N; i++) {
		for (j = i + 1; j < N; j++) {
			ll x1, x2, y1, y2;
			x1 = point[ord[i]].x;
			x2 = point[ord[j]].x;
			y1 = point[ord[i]].y;
			y2 = point[ord[j]].y;
			ll c1 = (-ccw(p1, p2, point[ord[i]]) * abs(a * x1 - b * y1 + c));
			ll c2 = (-ccw(p1, p2, point[ord[j]]) * abs(a * x2 - b * y2 + c));
			if (c1 > c2) swap(ord[i], ord[j]);
			else if (c1 == c2) {
				if (a * b > 0) {
					if (x2 > x1) swap(ord[i], ord[j]);
				}
				else if (a * b == 0) {
					if (x2 < x1) swap(ord[i], ord[j]);
				}
				else {
					if (x2 < x1) swap(ord[i], ord[j]);
				}
			}
		}
	}
	for (i = 0; i < N; i++) rev[ord[i]] = i;
	vector<ll> nv;
	nv.resize(N);
	for (i = 0; i < N; i++) nv[i] = val[ord[i]];
	seg = segtree(nv);
	ll ans = 0;
	for (i = 0; i < v.size(); i++) {
		pll x = v[i];
		if ((i == 0) || (!eq(v[i], v[i - 1]))) ans = max(ans, seg.maxall());
		swap(ord[rev[x.first]], ord[rev[x.second]]);
		swap(rev[x.first], rev[x.second]);
		seg.update(rev[x.first], val[x.first]);
		seg.update(rev[x.second], val[x.second]);
	}
	return ans;
}
signed main() {
	ios::sync_with_stdio(false), cin.tie(0);
	cin >> N;
	ll i, j;
	for (i = 0; i < N; i++) {
		ll x, y, c;
		cin >> x >> y >> c;
		point.push_back(Point(x, y));
		val.push_back(c);
	}
	ll ans = 0;
	ans = calc();
	for (i = 0; i < N; i++) swap(point[i].x, point[i].y);
	ans = max(ans, calc());
	cout << ans << ln;
}

Compilation message (stderr)

bulldozer.cpp: In function 'll calc()':
bulldozer.cpp:162:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  162 |  for (i = 0; i < v.size(); i++) {
      |              ~~^~~~~~~~~~
bulldozer.cpp: In function 'int main()':
bulldozer.cpp:175:8: warning: unused variable 'j' [-Wunused-variable]
  175 |  ll i, j;
      |        ^
#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...