319. Kalevich Strikes Back
Memory limit: 65536 kilobytes
output: standard
And yet again the Berland community can see that talent is always multi-sided. The talent is always seeking new ways of self-expression. This time genius Kalevich amazed everybody with his new painting "Rectangular Frames". The masterpiece is full of impenetrable meaning and hidden themes.
Narrow black rectangular frames are drawn on a white rectangular canvas. No two frames have a common point. Sides of each frame are parallel to the sides of the canvas.
The painting is very big and the reduced replica cannot pass the idea of the original drawing. That's why Kalevich requested that the simplified versions of the masterpiece should be used as replicas. The simplified version is the sequence of the areas of all facets of the original. A facet is a connected enclosed white area within the painting. The areas in the sequence should be written in the non-decreasing order.
The first line of the input contains an integer N (1 ≤ N ≤ 60000) — the number of the frames on the drawing. The second line contains integer numbers W and H (1 ≤ W, H ≤ 108).
Let's introduce the Cartesian coordinate system in such a way that the left bottom corner of the canvas has (0, 0) coordinate and the right top corner has the (W, H) coordinate. The sides of the canvas are parallel to the axes.
The following N lines contain the description of the frames. Each description is composed of the coordinates of the two opposite corners of the corresponding frame x1, y1, x2, y2(1 ≤ x1, x2 < W; 1 ≤ y1, y2 < H; x1 != x2, y1 != y2). All coordinates are integers. No two frames have a common point.
Write the desired sequence to the output.
sample input | sample output |
1 3 3 2 1 1 2 | 1 8 |
矩形不相交,可能会内含。
使用线段树的扫描线,搞出保含关系,然后dfs一遍。
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2014/5/1 16:10:22 4 File Name :E:\2014ACM\专题学习\数据结构\线段树\SGU319.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 const int MAXN = 120010; 21 struct Node 22 { 23 int l,r; 24 int ll,rr;//实际的左右区间 25 int c;//覆盖标记,懒惰标记 26 }segTree[MAXN*3]; 27 int x[MAXN]; 28 struct Line 29 { 30 int x1,x2,y; 31 int id; 32 Line(){} 33 Line(int _x1,int _x2,int _y,int _id) 34 { 35 x1 = _x1; 36 x2 = _x2; 37 y = _y; 38 id = _id; 39 } 40 }line[MAXN]; 41 bool cmp(Line a,Line b) 42 { 43 return a.y < b.y; 44 } 45 void push_down(int r) 46 { 47 if(segTree[r].l + 1 == segTree[r].r)return; 48 if(segTree[r].c != -1) 49 { 50 segTree[r<<1].c = segTree[(r<<1)|1].c = segTree[r].c; 51 segTree[r].c = -1; 52 } 53 } 54 void build(int i,int l,int r) 55 { 56 segTree[i].l = l; 57 segTree[i].r = r; 58 segTree[i].ll = x[l]; 59 segTree[i].rr = x[r]; 60 segTree[i].c = 0; 61 if(l+1 == r)return; 62 int mid = (l+r)/2; 63 build(i<<1,l,mid); 64 build((i<<1)|1,mid,r); 65 } 66 int pre[MAXN]; 67 void Update(int i,Line e) 68 { 69 if(segTree[i].ll == e.x1 && segTree[i].rr == e.x2) 70 { 71 if(e.id > 0) 72 segTree[i].c = e.id; 73 else segTree[i].c = pre[-e.id]; 74 return; 75 } 76 push_down(i); 77 if(e.x2 <= segTree[i<<1].rr)Update(i<<1,e); 78 else if(e.x1 >= segTree[(i<<1)|1].ll)Update((i<<1)|1,e); 79 else 80 { 81 Line tmp = e; 82 tmp.x2 = segTree[i<<1].rr; 83 Update(i<<1,tmp); 84 tmp = e; 85 tmp.x1 = segTree[(i<<1)|1].ll; 86 Update((i<<1)|1,tmp); 87 } 88 } 89 int query(int i,Line e) 90 { 91 if(segTree[i].c != -1) 92 return segTree[i].c; 93 if(e.x2 <= segTree[i<<1].rr)return query(i<<1,e); 94 else if(e.x1 >= segTree[(i<<1)|1].ll)return query((i<<1)|1,e); 95 else 96 { 97 e.x2 = segTree[i<<1].rr; 98 return query(i<<1,e); 99 } 100 } 101 long long area[MAXN]; 102 vector<int>vec[MAXN]; 103 void dfs(int u) 104 { 105 int sz = vec[u].size(); 106 for(int i = 0;i < sz;i++) 107 { 108 int v = vec[u][i]; 109 area[u] -= area[v]; 110 dfs(v); 111 } 112 } 113 114 int main() 115 { 116 //freopen("in.txt","r",stdin); 117 //freopen("out.txt","w",stdout); 118 int n; 119 int w,h; 120 while(scanf("%d",&n) == 1) 121 { 122 scanf("%d%d",&w,&h); 123 area[0] = (long long)w*h; 124 int x1,x2,y1,y2; 125 int tot = 0; 126 for(int i = 1;i <= n;i++) 127 { 128 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 129 if(x1 > x2)swap(x1,x2); 130 if(y1 > y2)swap(y1,y2); 131 area[i] = (long long)(x2-x1)*(y2-y1); 132 line[tot] = Line(x1,x2,y1,i); 133 x[tot++] = x1; 134 line[tot] = Line(x1,x2,y2,-i); 135 x[tot++] = x2; 136 } 137 sort(x,x+tot); 138 tot = unique(x,x+tot) - x; 139 build(1,0,tot-1); 140 sort(line,line+2*n,cmp); 141 for(int i = 0;i <= n;i++) 142 vec[i].clear(); 143 for(int i = 0;i < 2*n;i++) 144 { 145 if(line[i].id > 0) 146 { 147 pre[line[i].id] = query(1,line[i]); 148 vec[pre[line[i].id]].push_back(line[i].id); 149 } 150 Update(1,line[i]); 151 } 152 dfs(0); 153 sort(area,area+n+1); 154 for(int i = 0;i <= n;i++) 155 { 156 printf("%I64d",area[i]); 157 if(i < n)printf(" "); 158 else printf("\n"); 159 } 160 } 161 return 0; 162 }