萌新刚学 OI,线段树简单题 MLE 求卡
查看原帖
萌新刚学 OI,线段树简单题 MLE 求卡
377873
EricWan楼主2025/6/27 20:26

思路用的 zesqwq 大佬的,在校内搬运的题(数据强度稍弱)过了,因此正确性大概没问题,但是在这题被卡 MLE 了。

#include <bits/stdc++.h>
using namespace std;
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#define MAXN 1 << 21
struct rect_t {
	int u, d, l, r;
	bool used;
	void join(rect_t &b) {
		u = min(u, b.u);
		d = max(d, b.d);
		l = min(l, b.l);
		r = max(r, b.r);
		b.used = 1;
	}
	bool operator<(const rect_t &b) const {
		return d < b.d;
	}
	bool check(const rect_t &b) const {
		return l <= b.r && r >= b.l && u <= b.d && d >= b.u;
	}
} a[100005];
int n;
vector<int> vec1[MAXN], vec2[MAXN];
vector<int> new_join;
void sgt_update(int id, int l, int r, int rect_id) {
	vec2[id].push_back(rect_id);
	if (a[rect_id].l <= l && a[rect_id].r >= r) {
		vec1[id].push_back(rect_id);
		return;
	}
	if (a[rect_id].l <= (l + r) / 2) sgt_update(id * 2, l, (l + r) / 2, rect_id);
	if (a[rect_id].r > (l + r) / 2) sgt_update(id * 2 + 1, (l + r) / 2 + 1, r, rect_id);
}
void check(vector<int> &vec, int rect_id) {
	while (!vec.empty()) {
		if (a[vec.back()].used) {
			vec.pop_back();
			continue;
		}
		if (a[rect_id].check(a[vec.back()])) {
			new_join.push_back(vec.back());
			vec.pop_back();
		} else {
			break;
		}
	}
}
void sgt_check(int id, int l, int r, int rect_id)
{
	check(vec1[id], rect_id);
	if (a[rect_id].l <= l && a[rect_id].r >= r) {
		check(vec2[id], rect_id);
		return;
	}
	if (a[rect_id].l <= (l + r) / 2) sgt_check(id * 2, l, (l + r) / 2, rect_id);
	if (a[rect_id].r > (l + r) / 2) sgt_check(id * 2 + 1, (l + r) / 2 + 1, r, rect_id);
}
signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].u >> a[i].d >> a[i].l >> a[i].r;
		a[i].u++;
		a[i].l++;
	}
	sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; i++) {
		new_join.clear();
		sgt_check(1, 1, 1000000, i);
		while (!new_join.empty()) {
			for (int j : new_join) {
				a[i].join(a[j]);
			}
			new_join.clear();
			sgt_check(1, 1, 1000000, i);
		}
		sgt_update(1, 1, 1000000, i);
	}
	vector<pair<pair<int, int>, pair<int, int> > > ansans;
	for (int i = 1; i <= n; i++) {
		if (!a[i].used) {
			ansans.push_back({{a[i].u - 1, a[i].d}, {a[i].l - 1, a[i].r}});
		}
	}
	sort(ansans.begin(), ansans.end());
	cout << ansans.size() << endl;
	for (pair<pair<int, int>, pair<int, int> > i : ansans) {
		cout << i.first.first << " " << i.first.second << " " << i.second.first << " " << i.second.second << endl;
	}
	return 0;
}
2025/6/27 20:26
加载中...