zoukankan      html  css  js  c++  java
  • SGU 319. Kalevich Strikes Back (线段树)

    319. Kalevich Strikes Back

    Time limit per test: 0.5 second(s)
    Memory limit: 65536 kilobytes
    input: standard
    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.

    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 ≤ WH ≤ 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 (WH) 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 x1y1x2y2(1 ≤ x1x2 < W; 1 ≤ y1y2 < Hx1 != x2y1 != y2). All coordinates are integers. No two frames have a common point.

    Output

    Write the desired sequence to the output.

    Example(s)
    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("
    ");
    159         }
    160     }
    161     return 0;
    162 }
  • 相关阅读:
    HTML5 <meta> 标签属性,所有meta用法
    C#中导出数据到Excel表格中 逗号
    .net MVC 中缓存的使用 逗号
    MVC 过滤器 逗号
    .Net 分布式技术比较 逗号
    将DataTable导出为Excel (XML Spreadsheet).
    AntiTD
    三星WP7手机MANGO一分钟完美越狱
    SPGridView 研究笔记 Part 3 分组
    Silverlight 4 Binding Cheatsheet [转]
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3703850.html
Copyright © 2011-2022 走看看