Submission #1324673

#TimeUsernameProblemLanguageResultExecution timeMemory
1324673lesinhhungTiles (BOI24_tiles)C++20
100 / 100
91 ms11356 KiB
//    _____               __________      ______    ______
//   |    |              /    ___   \    |     |   |     |
//   |    |             /    /  |___|    |     |   |     |
//   |    |            |    \_____       |     |___|     |
//   |    |            \______    \      |      ____     |
//   |    |______     _____  \    |      |     |   |     |
//   |          |    |    |_/    /       |     |   |     |
//   |__________|    \__________/        |_____|   |_____|
//
//   Code boi Le Sinh Hung dep trai

#include <bits/stdc++.h>

using namespace std;

using lint = long long;
using pi = array<lint, 2>;
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(), (v).end()
#define cr(v, n) (v).clear(), (v).resize(n);

const int MAXT = 1050000;

lint ccw(pi a, pi b, pi c) {
	for (int i = 0; i < 2; i++)
		b[i] -= a[i], c[i] -= a[i];
	return b[0] * c[1] - c[0] * b[1];
}

int main() {
	ios::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("Tiles.Inp", "r", stdin);
//    freopen("Tiles.Out", "w", stdout);
//    
	int n, m;
	cin >> n >> m;
	vector<pi> a(n);
	for (auto &[x, y] : a) {
		cin >> x >> y;
	}
	{
		lint area = 0;
		for (int i = 2; i < n; i++) {
			area += ccw(a[0], a[i - 1], a[i]);
		}
		if (area < 0)
			reverse(all(a));
	}
	vector<array<int, 4>> v;
	for (int i = 0; i < n; i++) {
		if (a[i][0] == a[(i + 1) % n][0]) {
			int x = a[i][0];
			int l = a[i][1];
			int r = a[(i + 1) % n][1];
			if (l < r) {
				v.push_back({x, l, r, -1});
			} else {
				v.push_back({x, r, l, +1});
			}
		}
	}
	sort(all(v));
	int ans = 0;
	set<array<int, 3>> S;
	int odds = 0;
	int cnt[2] = {};
	auto INSERT = [&](array<int, 3> v) {
		if (v[0] % 2 != v[1] % 2)
			odds++;
		cnt[v[2]]++;
		S.insert(v);
	};
	auto ERASE = [&](array<int, 3> v) {
		if (v[0] % 2 != v[1] % 2)
			odds--;
		cnt[v[2]]--;
	};
	for (int i = 0; i < sz(v); i++) {
		auto [x, l, r, p] = v[i];
		if (p == -1) {
			vector<array<int, 3>> toput;
			auto it = S.lower_bound({l, -1, -1});
			if (it != S.begin() && (*prev(it))[1] > l) {
				it--;
			}
			while (it != S.end()) {
				auto [sl, sr, p] = *it;
				if (sl >= r)
					break;
				if (sl < l)
					toput.push_back({sl, l, p});
				if (r < sr)
					toput.push_back({r, sr, p});
				if (x % 2 != p) {
					cout << ans << "\n";
					return 0;
				}
				ERASE(*it);
				it = S.erase(it);
			}
			for (auto &z : toput)
				INSERT(z);
		} else {
			array<int, 3> toput = {l, r, x % 2};
			{
				auto it = S.lower_bound({r, -1, -1});
				if (it != S.end() && (*it)[0] == r && (*it)[2] == toput[2]) {
					toput[1] = (*it)[1];
					ERASE(*it);
					it = S.erase(it);
				}
			}
			{
				auto it = S.lower_bound({l, -1, -1});
				if (it != S.begin() && (*prev(it))[1] == l && (*prev(it))[2] == toput[2]) {
					it--;
					toput[0] = (*it)[0];
					ERASE(*it);
					it = S.erase(it);
				}
			}
			INSERT(toput);
		}
		if (i < sz(v) - 1 && v[i + 1][0] != v[i][0]) {
			int mask = 0;
			if (odds > 0) {
				cout << ans << "\n";
				return 0;
			}
			if (cnt[0])
				mask |= 1;
			if (cnt[1])
				mask |= 2;
			assert(mask > 0);
			if (mask == 1) {
				if (v[i + 1][0] % 2 == 0)
					ans = max(ans, v[i + 1][0]);
				else
					ans = max(ans, v[i + 1][0] - 1);
			} else if (mask == 2) {
				if (v[i + 1][0] % 2 == 1)
					ans = max(ans, v[i + 1][0]);
				else
					ans = max(ans, v[i + 1][0] - 1);
			}
		}
	}
	ans = m;
	cout << ans << "\n";
	
	return 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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...