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 |
1 8 |
矩形不相交,可能会内含。
使用线段树的扫描线,搞出保含关系,然后dfs一遍。
/* ***********************************************
Author :kuangbin
Created Time :2014/5/1 16:10:22
File Name :E:\2014ACM\专题学习\数据结构\线段树\SGU319.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
struct Node
{
int l,r;
int ll,rr;//实际的左右区间
int c;//覆盖标记,懒惰标记
}segTree[MAXN*];
int x[MAXN];
struct Line
{
int x1,x2,y;
int id;
Line(){}
Line(int _x1,int _x2,int _y,int _id)
{
x1 = _x1;
x2 = _x2;
y = _y;
id = _id;
}
}line[MAXN];
bool cmp(Line a,Line b)
{
return a.y < b.y;
}
void push_down(int r)
{
if(segTree[r].l + == segTree[r].r)return;
if(segTree[r].c != -)
{
segTree[r<<].c = segTree[(r<<)|].c = segTree[r].c;
segTree[r].c = -;
}
}
void build(int i,int l,int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].ll = x[l];
segTree[i].rr = x[r];
segTree[i].c = ;
if(l+ == r)return;
int mid = (l+r)/;
build(i<<,l,mid);
build((i<<)|,mid,r);
}
int pre[MAXN];
void Update(int i,Line e)
{
if(segTree[i].ll == e.x1 && segTree[i].rr == e.x2)
{
if(e.id > )
segTree[i].c = e.id;
else segTree[i].c = pre[-e.id];
return;
}
push_down(i);
if(e.x2 <= segTree[i<<].rr)Update(i<<,e);
else if(e.x1 >= segTree[(i<<)|].ll)Update((i<<)|,e);
else
{
Line tmp = e;
tmp.x2 = segTree[i<<].rr;
Update(i<<,tmp);
tmp = e;
tmp.x1 = segTree[(i<<)|].ll;
Update((i<<)|,tmp);
}
}
int query(int i,Line e)
{
if(segTree[i].c != -)
return segTree[i].c;
if(e.x2 <= segTree[i<<].rr)return query(i<<,e);
else if(e.x1 >= segTree[(i<<)|].ll)return query((i<<)|,e);
else
{
e.x2 = segTree[i<<].rr;
return query(i<<,e);
}
}
long long area[MAXN];
vector<int>vec[MAXN];
void dfs(int u)
{
int sz = vec[u].size();
for(int i = ;i < sz;i++)
{
int v = vec[u][i];
area[u] -= area[v];
dfs(v);
}
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
int w,h;
while(scanf("%d",&n) == )
{
scanf("%d%d",&w,&h);
area[] = (long long)w*h;
int x1,x2,y1,y2;
int tot = ;
for(int i = ;i <= n;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1 > x2)swap(x1,x2);
if(y1 > y2)swap(y1,y2);
area[i] = (long long)(x2-x1)*(y2-y1);
line[tot] = Line(x1,x2,y1,i);
x[tot++] = x1;
line[tot] = Line(x1,x2,y2,-i);
x[tot++] = x2;
}
sort(x,x+tot);
tot = unique(x,x+tot) - x;
build(,,tot-);
sort(line,line+*n,cmp);
for(int i = ;i <= n;i++)
vec[i].clear();
for(int i = ;i < *n;i++)
{
if(line[i].id > )
{
pre[line[i].id] = query(,line[i]);
vec[pre[line[i].id]].push_back(line[i].id);
}
Update(,line[i]);
}
dfs();
sort(area,area+n+);
for(int i = ;i <= n;i++)
{
printf("%I64d",area[i]);
if(i < n)printf(" ");
else printf("\n");
}
}
return ;
}