思路用的 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;
}