Description
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.
Input
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 ≤ 10
8).
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 x 1, y 1, x 2, y 2 (1 ≤ x 1, x 2 < W; 1 ≤ y 1, y 2 < H; x 1 != x 2, y 1 != y 2). All coordinates are integers. No two frames have a common point.
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 x 1, y 1, x 2, y 2 (1 ≤ x 1, x 2 < W; 1 ≤ y 1, y 2 < H; x 1 != x 2, y 1 != y 2). All coordinates are integers. No two frames have a common point.
Output
Write the desired sequence to the output.
Sample Input
1 3 3 2 1 1 2
Sample Output
1 8
线段树搞了好几天,终于今天来灵感了。找父边框
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <queue>
#include <set>
#include <map>
#pragma comment (linker,"/STACK:102400000,102400000")
#define N 130000
#define M 60010
using namespace std;
struct num
{
int l,r;
int tag,x,y1,y2;
int id;
}a[4*N],b[N];
struct inf
{
int l,r;
}e[M];
struct Num
{
int y,next;
}c[M];
int d[M];
int pre[M];
__int64 ans[N];
int point[N],Top;
map<int,int>ma;
bool cmp(num p1,num p2)
{
return p1.x<p2.x;
}
int main()
{
//freopen("data.txt","r",stdin);
void addeage(int x,int y);
void build(int k,int l,int r);
int find(int k,int l,int r);
void update(int k,int l,int r,int id);
void dfs(int k);
int n;
while(scanf("%d",&n)!=EOF)
{
int h,w;
scanf("%d %d",&w,&h);
b[1].tag = 1;
b[1].x = 0;
b[1].y1 = 0;
b[1].y2 = h;
b[1].id = 1;
point[1] = 0;
b[2].tag = -1;
b[2].x = w;
b[2].y1 = 0;
b[2].y2 = h;
b[2].id = 1;
point[2] = h;
e[1].l = w;
e[1].r = h;
for(int i=2;i<=n+1;i++)
{
int x1,y1,x2,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
if(x1>x2)
{
swap(x1,x2);
swap(y1,y2);
}
if(y1>y2)
{
swap(y1,y2);
}
e[i].l = x2-x1;
e[i].r = y2-y1;
b[i*2-1].tag = 1;
b[i*2-1].x = x1;
b[i*2-1].y1 = y1;
b[i*2-1].y2 = y2;
b[i*2-1].id = i;
point[i*2-1] = y1;
b[i*2].tag = -1;
b[i*2].x = x2;
b[i*2].y1 = y1;
b[i*2].y2 = y2;
b[i*2].id = i;
point[i*2] = y2;
}
n = n+1;
sort(b+1,b+2*n+1,cmp);
sort(point,point+2*n+1);
Top =1;
ma.clear();
ma[point[1]] = 1;
int fa = point[1];
for(int i=2;i<=2*n;i++)
{
if(point[i]!=fa)
{
Top++;
point[Top] = point[i];
ma[point[i]] = Top;
fa = point[i];
}
}
build(1,1,Top);
memset(d,-1,sizeof(d));
Top = 0;
for(int i=2;i<=2*n-1;i++)
{
int tag = b[i].tag;
int y1 = ma[b[i].y1];
int y2 = ma[b[i].y2];
int id = b[i].id;
if(tag==-1)
{
update(1,y1,y2,pre[id]);
}else
{
int k = find(1,y1,y1+1);
//cout<<y1<<" "<<y2<<" "<<id<<endl;
pre[id] = k;
addeage(k,id);
update(1,y1,y2,id);
}
}
Top = 1;
dfs(1);
sort(ans+1,ans+Top);
for(int i=1;i<=Top-1;i++)
{
if(i==1)
{
printf("%I64d",ans[i]);
}else
{
printf(" %I64d",ans[i]);
}
}
printf("\n");
}
return 0;
}
void addeage(int x,int y)
{
c[Top].y =y;
c[Top].next =d[x];
d[x] = Top++;
}
void pushup(int k)
{
a[k].tag = 0;
if(a[k<<1].tag==1&&a[k<<1|1].tag==1&&a[k<<1].id==a[k<<1|1].id)
{
a[k].tag = 1;
a[k].id = a[k<<1].id;
}
}
void build(int k,int l,int r)
{
a[k].l = l;
a[k].r = r;
a[k].id = 1;
a[k].tag = 1;
if(l+1==r)
{
return ;
}
int mid = (l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid,r);
pushup(k);
}
int find(int k,int l,int r)
{
if(a[k].tag==1)
{
return a[k].id;
}
int mid = (a[k].l+a[k].r)>>1;
if(mid>=r)
{
return find(k<<1,l,r);
}else if(mid<=l)
{
return find(k<<1|1,l,r);
}
}
void update(int k,int l,int r,int id)
{
if(a[k].l==l&&a[k].r==r)
{
a[k].id = id;
a[k].tag = 1;
return ;
}
if(a[k].tag==1)
{
a[k<<1].tag = 1;
a[k<<1].id = a[k].id;
a[k<<1|1].tag = 1;
a[k<<1|1].id = a[k].id;
}
int mid = (a[k].l+a[k].r)>>1;
if(mid>=r)
{
update(k<<1,l,r,id);
}else if(mid<=l)
{
update(k<<1|1,l,r,id);
}else
{
update(k<<1,l,mid,id);
update(k<<1|1,mid,r,id);
}
pushup(k);
}
void dfs(int k)
{
__int64 res = (__int64)e[k].l*(__int64)e[k].r;
for(int i=d[k];i!=-1;i=c[i].next)
{
int u = c[i].y;
dfs(u);
res-=(__int64)e[u].l*(__int64)e[u].r;
}
ans[Top++] = res;
}