• 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 }
  • 相关阅读:
    _src_求和案例_mapState与mapGetters
    _src_求和案例_mapMutations与mapActions
    _src_求和案例_多组件共享数据
    LLVM基础学习:LLVM的编译安装和基本使用
    LLVM基础学习:使用GDB调试一个outoftree的 LLVM Pass
    2022 618笔记本选购指北
    PHP中SERVER_NAME获取的问题
    一天一个仿lodash函数实现fill、findIndex、first、head
    一天一个仿lodash函数实现flatten
    一天一个仿lodash函数实现keyBy、groupBy、find
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3703850.html
Copyright © 2020-2023  润新知