标签:坐标 line inline 构造 amp const codeforce return int()
定义一个点集是“好的”,那么其中任意两点之间满足下列三个条件之一:
现在有 \(n\) 个点,找到一种添加点的方案,使得这个集合是“好的”。
构造其中一组总点数不超过 \(2\times 10^5\) 的可行解。
平面分治。
假如将点按 \(x\) 坐标排序,取中间点的 \(x\) 坐标作为中间线的 \(x\) 坐标,然后对所有点做这个中间线上的 投影,所形成的点就是要添加的点。加入这些点之后,可以发现中间线异侧的点对全都满足条件。
那同侧的呢?使用 踢皮球大法 递归处理。于是做好了。如果要判断重复点的话只要用一个 set
就好了。
#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;
}
标签:坐标 line inline 构造 amp const codeforce return int()
原文地址:https://www.cnblogs.com/-Wallace-/p/12874003.html