「Codeforces 97B」Superset
Posted -wallace-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「Codeforces 97B」Superset相关的知识,希望对你有一定的参考价值。
Description
定义一个点集是“好的”,那么其中任意两点之间满足下列三个条件之一:
- 横坐标相同
- 纵坐标相同
- 以这两个点为顶点的长方形包含(在内部或边缘)其他的至少一个点。
现在有 (n) 个点,找到一种添加点的方案,使得这个集合是“好的”。
构造其中一组总点数不超过 (2 imes 10^5) 的可行解。
Hint
- (1le nle 10^4)
- (| ext{坐标大小}| le 10^9)
Solution
平面分治。
假如将点按 (x) 坐标排序,取中间点的 (x) 坐标作为中间线的 (x) 坐标,然后对所有点做这个中间线上的 投影,所形成的点就是要添加的点。加入这些点之后,可以发现中间线异侧的点对全都满足条件。
那同侧的呢?使用 踢皮球大法 递归处理。于是做好了。如果要判断重复点的话只要用一个 set
就好了。
Code
#include <algorithm>
#include <iostream>
#include <set>
using namespace std;
const int N = 2e5 + 5;
struct Point {
int x, y;
inline Point() { }
inline Point(int _x, int _y) : x(_x), y(_y) { }
inline bool operator < (const Point& t) const {
return x != t.x ? x < t.x : y < t.y;
}
} p[N];
set<Point> points;
int n;
void solve(int l, int r) {
if (l == r) return;
int mid = (l + r) >> 1, x = p[mid].x;
solve(l, mid), solve(mid + 1, r);
for (register int i = l; i <= r; i++)
points.insert(Point(x, p[i].y));
}
signed main() {
ios::sync_with_stdio(false);
cin >> n;
for (register int i = 1; i <= n; i++)
cin >> p[i].x >> p[i].y;
for (register int i = 1; i <= n; i++)
points.insert(p[i]);
sort(p + 1, p + 1 + n);
solve(1, n);
cout << points.size() << endl;
for (set<Point>::iterator it = points.begin(); it != points.end(); it++)
cout << it->x << ‘ ‘ << it->y << endl;
return 0;
}
以上是关于「Codeforces 97B」Superset的主要内容,如果未能解决你的问题,请参考以下文章
A - Superset CodeForces - 97B(人生第一个分治法,感觉,像二分啊。。)
Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 树状数组维护区间最大值(示(代
ICM Technex 2018 and Codeforces Round #463 (Div. 1 + Div. 2, combined) A Palindromic Supersequence(代