CF97B Superset

传送门

这题一看非常蒙 因为要求太宽了

一开始可以秒掉就是用一条水平/竖直折线连接所有点 所有的拐点输出就行

总共已知的点数是1e4 也就是说总点数要加成nlgn

想到分治 二分中线然后所有点往中线投影 一共分lgn次 满足题意

注意去重 开个set重载==就可以

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #include<iostream>
 7 #define ms(a,b) memset(a,b,sizeof a)
 8 #define rep(i,a,n) for(int i = a;i <= n;i++)
 9 #define per(i,n,a) for(int i = n;i >= a;i--)
10 #define inf 1e18
11 using namespace std;
12 typedef long long ll;
13 typedef double D;
14 #define eps 1e-8
15 ll read() {
16     ll as = 0,fu = 1;
17     char c = getchar();
18     while(c < '0' || c > '9') {
19         if(c == '-') fu = -1;
20         c = getchar();
21     }
22     while(c >= '0' && c <= '9') {
23         as = as * 10 + c - '0';
24         c = getchar();
25     }
26     return as * fu;
27 }
28 const int N = 200005;
29 //head
30 int n;
31 struct node {
32     int x,y;
33     bool operator < (const node &o) const {
34         return x == o.x ? y < o.y : x < o.x;
35     }
36     bool operator == (const node &o) const {
37         return x == o.x && y == o.y;
38     }
39 }p[N],ans[N<<2];
40 int top = 0;
41 //[l,r)
42 void solve(int l,int r) {
43     if(l >= r) return;
44     int m = l+r >> 1;
45     rep(i,l,r) ans[++top] = (node){p[m].x,p[i].y};
46     solve(l,m),solve(m+1,r);
47 }
48 
49 int main() {
50     n = read();
51     rep(i,1,n) {
52         p[i].x = read(),p[i].y = read();
53         ans[++top] = p[i];
54     }
55     sort(p+1,p+n+1),solve(1,n);
56     sort(ans+1,ans+1+top);
57     top = unique(ans+1,ans+1+top) - (ans+1);
58     printf("%d
",top);
59     rep(i,1,top) printf("%d %d
",ans[i].x,ans[i].y);
60     return 0;
61 }

CF97B Superset

原文地址:https://www.cnblogs.com/yuyanjiaB/p/10043483.html