Kalevich Strikes Back

W - Kalevich Strikes Back
Time Limit:500MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u

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.

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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值