题意:

       给你n个矩形,每个矩形上都有一个矩形的空洞,所有的矩形都是平行于x,y轴的,最后问所有矩形的覆盖面积是多少。

思路:

      是典型的矩形覆盖问题,只不过每个矩形上多了一个矩形洞,我的做法是吧当前的矩形分成四个小的矩形,然后用线段树的扫描线扫一遍就ok了,记得要用INT64 ,自己没注意这个问题wa了一次。


#include<stdio.h>
#include<string.h>
#include<algorithm> #define N 300000
#define lson l ,mid ,t << 1
#define rson mid ,r ,t << 1 | 1

using namespace
std; typedef struct
{
__int64
l ,r ,h ,mk;
}
EDGE; __int64 len[N] ,cnt[N];
EDGE edge[N*2]; bool camp(EDGE a ,EDGE b)
{
return
a.h < b.h || a.h == b.h && a.mk > b.mk;
} void
Pushup(__int64 l ,__int64 r ,__int64 t)
{
if(
cnt[t]) len[t] = r - l;
else if(
l + 1 == r) len[t] = 0;
else
len[t] = len[t<<1] + len[t<<1|1];
} void
Update(__int64 l ,__int64 r ,__int64 t ,__int64 a ,__int64 b ,__int64 c)
{

//printf("%d %d %d\n" ,l ,r ,t);
if(l == a && r == b)
{

cnt[t] += c;
Pushup(l ,r ,t);
return;
}
__int64
mid = (l + r) >> 1;
if(
b <= mid) Update(lson ,a ,b ,c);
else if(
a >= mid) Update(rson ,a ,b ,c);
else
{

Update(lson ,a ,mid ,c);
Update(rson ,mid ,b ,c);
}

Pushup(l ,r ,t);
} __int64
abss(__int64 x)
{
return
x < 0 ? -x : x;
} int main ()
{
__int64
i ,j ,n ,x1 ,x2 ,x3 ,x4 ,y1 ,y2 ,y3 ,y4 ,id;
__int64
xx1 ,xx2 ,yy1 ,yy2;
while(~
scanf("%I64d" ,&n) && n)
{
for(
id = 0 ,i = 1 ;i <= n ;i ++)
{

scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d" ,&x1 ,&y1 ,&x2 ,&y2 ,&x3 ,&y3 ,&x4 ,&y4);
x1 ++ ,y1 ++ ,x2 ++ ,y2 ++ ,x3 ++ ,y3 ++ ,x4 ++ ,y4 ++;
// x1 y2 x2 y4
xx1 = x1 ,xx2 = x2 ,yy1 = y2 ,yy2 = y4;
if(
abss(xx1 - xx2) && abss(yy1 - yy2))
{

edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy1 ,edge[id].mk = 1; edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy2 ,edge[id].mk = -1;
}

// x1 y3 x2 y1
xx1 = x1 ,xx2 = x2 ,yy1 = y3 ,yy2 = y1;
if(
abss(xx1 - xx2) && abss(yy1 - yy2))
{

edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy1 ,edge[id].mk = 1; edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy2 ,edge[id].mk = -1;
}
// x1 y4 x3 y3
xx1 = x1 ,xx2 = x3 ,yy1 = y4 ,yy2 = y3;
if(
abss(xx1 - xx2) && abss(yy1 - yy2))
{

edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy1 ,edge[id].mk = 1; edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy2 ,edge[id].mk = -1;
}
// x4 y4 x2 y3
xx1 = x4 ,xx2 = x2 ,yy1 = y4 ,yy2 = y3;
if(
abss(xx1 - xx2) && abss(yy1 - yy2))
{

edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy1 ,edge[id].mk = 1; edge[++id].l = xx1;
edge[id].r = xx2 ,edge[id].h = yy2 ,edge[id].mk = -1;
}
}

sort(edge + 1 ,edge + id + 1 ,camp);
__int64
Ans = 0;
memset(len ,0 ,sizeof(len));
memset(cnt ,0 ,sizeof(cnt));
edge[0].h = edge[1].h;
for(
i = 1 ;i <= id ;i ++)
{

Ans += len[1] * (edge[i].h - edge[i-1].h);
Update(1 ,50001,1 ,edge[i].l ,edge[i].r ,edge[i].mk); }
printf("%I64d\n" ,Ans);
}
return
0;
}

     

hdu 3265 线段树扫描线(拆分矩形)的更多相关文章

  1. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  2. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  3. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  6. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  7. HDU 5107 线段树扫描线

    给出N个点(x,y).每一个点有一个高度h 给出M次询问.问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对全部的点和询 ...

  8. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  9. HDU 5091 线段树扫描线

    给出N个点.和一个w*h的矩形 给出N个点的坐标,求该矩形最多能够覆盖多少个点 对每一个点point(x.y)右边生成相应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍.遇到点则用 ...

随机推荐

  1. linux安装uwsgi,报错问题解决

    uwsgi安装 uwsgi启动后出 -- unavailable modifier requested: 0 出现问题的的原因是找不到python的解释器(其他语言同理) 你使用的yum instal ...

  2. dubbo实战之三:使用Zookeeper注册中心

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. 记录一个在配置虚拟环境是遇到的错误(virtualenv)

    原配置文件 export WORKON_HOME=~/Envs #设置virtualenv的统一管理目录 export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no- ...

  4. 如何使用python把json文件转换为csv文件

    @ 目录 了解json整体格式 转换格式 提取key和value 使用pandas写入csv 了解json整体格式 这里有一段json格式的文件,存着全球陆地和海洋的每年异常气温(这里只选了一部分): ...

  5. Codeforces Round #553 B. Dima and a Bad XOR

    题面: 传送门 题目描述: 题意很简单:在一个N*M的矩阵中(N行M列),问是否可以:每行选一个整数,使他们的异或和大于0.如果不可以,输出"NIE":如果可以,输出"T ...

  6. 【python+selenium的web自动化】- PageObject模式解析及案例

    如果想从头学起selenium,可以去看看这个系列的文章哦! https://www.cnblogs.com/miki-peng/category/1942527.html PO模式 ​ Page O ...

  7. “/”应用程序中的服务器错误。||分析器错误消息: 未能加载类型“WebApplication1._Default”

    环境VS2008 无法运行WEB项目,Winfrom程序OK. 新创建的WEB项目直接运行报下图错误. 尝试多种方法: 1,重新生成项目,运行.(失败) 2,重装VS2008(默认.完全.自定义)安装 ...

  8. nodeJS详解2

    Nodejs应用场景 创建应用服务 web开发 接口开发 客户端应用工具  gulp webpack vue脚手架 react脚手架 小程序 NodeJs基于 Commonjs模块化开发的规范,它定义 ...

  9. Android 之 使用 Intent 在活动间传递数据

    •前言 继上次学习了<通过 Intent 完成点击按钮实现页面跳转>后,我们知道了如何通过 Intent 实现页面跳转: Intent 除了可以实现页面跳转外,还可以在跳转的时候传递数据: ...

  10. Android Studio 中的 button 无法使用 background 更改背景颜色

    •解决方案 res/values/themes.xml下的  <style name="Theme.HelloWorld" parent="Theme.Materi ...