题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265

题意:给你一张挖了洞的墙纸贴在墙上,问你总面积有多少。

挖了洞后其实就是多了几个矩形墙纸,一张墙纸挖了洞后可以分成4个小矩形至于怎么分看个人喜好,然后再求个矩形的面积并

要注意的是x1==x3||x2==x4||y1==y3||y2==y4时不用分矩形这是个小小的优化。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M = 5e4 + 10;
struct ss {
int l , r , h , flag;
}s[M << 3];
struct TnT {
int l , r , len , add;
}T[M << 3];
bool cmp(ss a , ss b) {
return a.h < b.h;
}
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r , T[p].add = 0 , T[p].len = 0;
if(l == r)
return ;
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
}
void pushup(int p) {
if(T[p].add) {
T[p].len = T[p].r - T[p].l + 1;
}
else if(T[p].l == T[p].r) {
T[p].len = 0;
}
else {
T[p].len = T[p << 1].len + T[(p << 1) | 1].len;
}
}
void updata(int l , int r , int p , int ad) {
int mid = (T[p].l + T[p].r) >> 1;
if(T[p].l == l && T[p].r == r) {
T[p].add += ad;
pushup(p);
return ;
}
if(mid >= r) {
updata(l , r , p << 1 , ad);
}
else if(mid < l) {
updata(l , r , (p << 1) | 1 , ad);
}
else {
updata(l , mid , p << 1 , ad);
updata(mid + 1 , r , (p << 1) | 1 , ad);
}
pushup(p);
}
int main() {
int n;
while(scanf("%d" , &n) != EOF) {
if(n == 0)
break;
int gg = 0;
int x1 , x2 , x3 , x4 , y1 , y2 , y3 , y4;
int MAX = 0;
for(int i = 1 ; i <= n ; i++) {
scanf("%d%d%d%d%d%d%d%d" , &x1 , &y1 , &x2 , &y2 , &x3 , &y3 , &x4 , &y4);
x1++ , x2++ , x3++ , x4++ , y1++ , y2++ , y3++ , y4++;
MAX = max(max(max(x1 , x2) , max(x3 , x4)) , MAX);
if(x1 != x3) {
s[++gg].flag = -1;
s[gg].l = x1;
s[gg].r = x3;
s[gg].h = y4;
s[++gg].flag = 1;
s[gg].l = x1;
s[gg].r = x3;
s[gg].h = y3;
}
if(x2 != x4) {
s[++gg].flag = -1;
s[gg].l = x4;
s[gg].r = x2;
s[gg].h = y4;
s[++gg].flag = 1;
s[gg].l = x4;
s[gg].r = x2;
s[gg].h = y3;
}
if(y1 != y3) {
s[++gg].flag = -1;
s[gg].l = x1;
s[gg].r = x2;
s[gg].h = y3;
s[++gg].flag = 1;
s[gg].l = x1;
s[gg].r = x2;
s[gg].h = y1;
}
if(y2 != y4) {
s[++gg].flag = -1;
s[gg].l = x1;
s[gg].r = x2;
s[gg].h = y2;
s[++gg].flag = 1;
s[gg].l = x1;
s[gg].r = x2;
s[gg].h = y4;
}
}
sort(s + 1 , s + 1 + gg , cmp);
build(1 , MAX , 1);
int l , r;
l = s[1].l;
r = s[1].r - 1;
updata(l , r , 1 , s[1].flag);
long long area = 0;
for(int i = 2 ; i <= gg ; i++) {
area += (long long)T[1].len * (s[i].h - s[i - 1].h);
l = s[i].l;
r = s[i].r - 1;
updata(l , r , 1 , s[i].flag);
}
printf("%lld\n" , area);
}
return 0;
}

hdu 3265 Posters(线段树+扫描线+面积并)的更多相关文章

  1. HDU 3265 Posters (线段树+扫描线)(面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩 ...

  2. 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提

    给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...

  3. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  4. poj1511,线段树扫描线面积

    经典题,线段树扫描线其实类似区间更新,一般的做法是想象一根扫描线从上扫到下或者从左扫到右,本题的做法是从上扫到下 只要扫到了一根水平线,就将其更新到线段树对应区间中,区间和它的子区间是独立更新的 #i ...

  5. hdu 1542 Atlantis (线段树扫描线)

    大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...

  6. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. HDU 1255 覆盖的面积 (线段树扫描线+面积交)

    自己YY了一个的写法,不过时间复杂度太高了,网上的想法太6了  题意:给你一些矩阵,求出矩阵的面积并 首先按照x轴离散化线段到线段树上(因为是找连续区间,所以段建树更加好做). 然后我们可以想一下怎样 ...

  8. hdu 1542(线段树+扫描线 求矩形相交面积)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  9. HDU 1828 Picture (线段树+扫描线)(周长并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828 给你n个矩形,让你求出总的周长. 类似面积并,面积并是扫描一次,周长并是扫描了两次,x轴一次,y ...

随机推荐

  1. Java课堂 动手动脑6

    一.下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么? m=d;d=m;d=(Dog)m;d=c;c=(Cat)m; 先进行自我判断, 1.代码: class Mammal{} c ...

  2. curl工具使用实例

    curl是一个命令行工具,其基于libcurl库,用于发送网络请求,获取并展示响应数据,下面来看curl的具体用法. 1.下载网页源码 curl命令直接接URL,用于下载指定URL的网页源码,并将其显 ...

  3. android ——Tablayout

    Tabs make it easy to explore and switch between different views. 通过TabLayout可以在一个活动中通过滑动或者点击切换到不同的页面 ...

  4. 认识Linux工具

    Centos7镜像网站:清华,阿里,网易 软件安装:lamp   httpd (认识) yum: 安装工具    需要选版本和特性,所以生产不用yum rpm:安装依赖 源码编译 shell脚本:yu ...

  5. 编程使用c#连接到IBM db2的两种方式

    一:使用c#通过odbc连接到IBM db2使用 ConnectionString 属性连接到各种数据源. 部署:只要在客户端安装IBM DB2 ODBC driver.配置DSn即可. 1):可以单 ...

  6. 【Python3爬虫】学习分布式爬虫第一步--Redis分布式爬虫初体验

    一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对I ...

  7. vue 使用gojs绘制简单的流程图

    在vue项目中需要展示工作流进度,可以使用的流程图插件很多 flowchart.js  http://adrai.github.io/flowchart.js/ , 基于SVG创建Flow Chart ...

  8. 「雕爷学编程」Arduino动手做(15)——手指侦测心跳模块

    37款传感器和模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器与模块,依照实践出真知(动手试试)的理念,以学习和交流为目的,这里准备 ...

  9. 常用高效 Java 工具类总结

    一.前言 在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类.以下工具类.方法按使用流行度排名,参考数据来源于Github上随机选取的5万个开源项目源码 ...

  10. maven学习(3)pom.xml文件说明以及常用指令

    pom.xml文件的结构: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:/ ...