HDU3265 扫描线+线段树 区间并

45人阅读 评论(0) 收藏 举报
分类:

传送门:HDU3265

题意:N个海报,每个海报中间有个矩形的洞。问这N个海报覆盖面积和是多少。


分析: 非常经典的题目了,扫描线+线段树 进行 区间并操作 

既然海报内有块矩形不能计算入内,只要把海报分为四块不重叠的部分就好了。

重点是空间限制比较紧,交了若干次才A的。。改用unsigned short(0...65536) 存储坐标才A了。。

注意:若扫描线个数小于2直接输出0,如果按常规的线段树求区间和会返回RE。。


截图纪念一下这个让我调试了N久bug的题目。。



代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 4e5+10;
struct Line{
   unsigned short x,y1,y2;
   bool f;
   bool operator <(const Line &rhs) const {
      return x<rhs.x;
   }
}line[maxn];
int y[maxn];
int n,tot;

inline void addLine(int a, int b,int c, int d) {
   tot++;
   line[tot].x = a; line[tot].y1 = b; line[tot].y2 = d;
   line[tot].f = 1; y[tot] = b;
   tot++;
   line[tot].x = c; line[tot].y1 = b; line[tot].y2 = d;
   line[tot].f = 0; y[tot] = d;
}

struct node{
    int l,r;
    int c,len;
    int lf,rf;
};

struct Tree{
     node tr[maxn*4];
     #define lch(u) (u<<1)
     #define rch(u) (u<<1|1)
     #define Mid (tr[u].l+tr[u].r)>>1

     void build(int u, int a, int b) {
         tr[u].l = a; tr[u].r = b;
         tr[u].lf = y[a]; tr[u].rf = y[b];
         tr[u].c = tr[u].len = 0;
         if (a+1 == b) return ;
         build(lch(u),a,Mid);
         build(rch(u),Mid,b);
     }

    inline void cal(int u){
         if (tr[u].c > 0) {
             tr[u].len = tr[u].rf - tr[u].lf;
         }
         else {
            if (tr[u].l+1 == tr[u].r) tr[u].len = 0;
            else tr[u].len = tr[lch(u)].len + tr[rch(u)].len;
         }
     }

     void update(int u, Line e){
         if (e.y1 == tr[u].lf && e.y2 == tr[u].rf) {
            if (e.f == 1) tr[u].c++; else tr[u].c--;
            cal(u);
            return ;
         }
         if (e.y2 <= tr[lch(u)].rf) update(lch(u),e);
         else if (e.y1 >= tr[rch(u)].lf) update(rch(u),e);
         else {
            Line tmp = e;
            tmp.y2 = tr[lch(u)].rf;
            update(lch(u),tmp);

            tmp = e;
            tmp.y1 = tr[rch(u)].lf;
            update(rch(u),tmp);
         }
         cal(u);
     }
}T;

int x[10];

int main(){
    while (scanf("%d",&n)==1 && n){
        tot = 0;
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=8; j++) scanf("%d",&x[j]);
            if (x[1]<x[5] && x[2]<x[4]) addLine(x[1],x[2],x[5],x[4]);
            if (x[7]<x[3] && x[2]<x[4]) addLine(x[7],x[2],x[3],x[4]);
            if (x[5]<x[7] && x[8]<x[4]) addLine(x[5],x[8],x[7],x[4]);
            if (x[5]<x[7] && x[2]<x[6]) addLine(x[5],x[2],x[7],x[6]);
        }
        sort(line+1,line+tot+1);
        sort(y+1,y+tot+1);

        if (tot<2) {
            printf("0\n");
            continue;
        }

        T.build(1,1,tot);
        T.update(1,line[1]);

        unsigned int ans = 0;
        for (int i=2; i<=tot; i++) {
            ans += T.tr[1].len*(line[i].x-line[i-1].x);
            T.update(1,line[i]);
        }
        printf("%u\n",ans);
    }
    return 0;
}

查看评论

HDU3265_Posters(扫描线/线段树)

解题报告 题意: 给定的矩形里面有镂空的矩阵,求矩阵面积并。 思路: 直接把一个图形拆成4个矩形,进行面积并。 扫描线+线段树 #include #include #include ...
  • u013320038
  • u013320038
  • 2014-08-16 20:06:32
  • 2451

HDU3265 线段树 线扫描

传送门:点击打开链接 Posters Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other...
  • w703710691d
  • w703710691d
  • 2014-12-30 19:26:56
  • 241

hdu 1542 矩形面积并(扫描线+线段树)

【题目链接】 http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14795 【解题报告】 七月的时候做过扫描线线段树,那个时...
  • gungnir0711
  • gungnir0711
  • 2015-12-16 07:46:45
  • 827

HDU 1828 线段树之扫描线之周长并

点击打开链接 题意:给n个矩形,求它们重叠后的周长 思路:用线段树的扫描线从下到上扫一遍,与面积并思想有些相似面积并,下面重边的处理相似,但是周长的并需要求的是竖边的个数然后乘以高度,而面积并求的...
  • Dan__ge
  • Dan__ge
  • 2016-03-25 11:41:49
  • 717

线段树辅助——扫描线法计算矩形周长并(轮廓线)

例题:hdu 1828 Picture 有两种方法,不过常用的第二种,两种都说一下。 第一种: 把矩形分成横线和竖线去处理,可知是完全相同的操作,我们来讲下怎么算出横线部分,竖线...
  • chaoweilanmao
  • chaoweilanmao
  • 2015-05-17 20:52:53
  • 640

hdu 1542 扫描线+线段树求矩阵面积并

这几天想啃啃树,无意中找到了这个题,一方面练习一下线段树,另一方面学习一下离散化和扫描线的技巧。       首先,离散化是必要的,因为x,y       显然,离散化的数据不会有重复,这里要介绍...
  • EzCUfST
  • EzCUfST
  • 2015-08-01 19:54:26
  • 1063

POJ 2482 Stars in Your Window (线段树区间合并+扫描线)

这题开始一直被矩形框束缚了,想法一直都是枚举线,但是这样枚举都需要O(n^2)。。。但是看了别人的思路,感觉这题思想真心很好(PS:开头好浪漫的描述啊,可惜并没有什么用) 题意就是在平面上给你一些星...
  • qq_33530115
  • qq_33530115
  • 2016-08-29 12:09:48
  • 367

HDU 1542 Atlantis(线段树:扫描线)

HDU1542 Atlantis(线段树:扫描线) 题意: 二维平面有n个平行于坐标轴的矩形,现在要求出这些矩形的总面积. 重叠部分只能算一次. 分析:        首先假设有下图两个矩阵,我们如果...
  • u013480600
  • u013480600
  • 2014-03-30 01:46:38
  • 3636

【解题报告】POJ1151 扫描线+线段树(矩形求并)

先贴题目链接吧:http://poj.org/problem?id=1151 今年刚参加完蓝桥杯,第十题就是一道扫描线求矩形面积并的问题,当时还没学习扫描线,有思路但是不会实现,于是花了两天时间好好...
  • Desico
  • Desico
  • 2017-04-14 18:11:45
  • 354

矩形面积并、矩形面积交、矩形周长并(线段树、扫描线总结)

HDU 1542 [POJ 1151] Atlantis (矩形面积并) 题意: 求N
  • lwt36
  • lwt36
  • 2015-10-05 01:24:45
  • 4706
    个人资料
    持之以恒
    等级:
    访问量: 3万+
    积分: 2606
    排名: 1万+
    最新评论