这道题最开始我以为和HDU - 1542 那道题一样,只需要把cover次数改成2次即可,但是后面仔细一想,我们需要求的是覆盖次数大于等于2次的,这样的话,我们需要维护两个长度,HDU-1542 由于求的是覆盖次数大于等于一次的,我们只需要维护一个覆盖次数大于等于1的长度的len1就行,但是这道题我们要求的是覆盖两次以及两次以上的长度,这样乘以高度差,才是面积。

现在我们来想如何维护这个值?

给线段树打个标记cover,代表这个区间被完全覆盖的次数。

我们先来看看,维护覆盖一次及其以上的,应该怎么实现,我们可以从中得到启示。

  1. cover不为0 那么这个区间被完全覆盖。我们把整个区间长度给len1,但是我们由于经过离散化。表达式为:tree[root].len1=pos[r+1]-pos[l]
  2. L==R 代表跑到了叶子节点,不会有节点信息往上传,因此赋0
  3. 不满足上述两者,我们就可以认为,父节点的信息,又两个儿子节点的提供。

那么覆盖两次的呢?同样的分情况讨论

  1. cover>1 那么这个区间内被完全覆盖至少2次,值等于区间长度。
  2. L==R 同样的信息不能由子节点提供,赋0。
  3. Cover==1 那么这个区间被完全覆盖至少一,子节点覆盖次数大于等于1的次数往上pushup后,变成至少两次。
  4. 反之节点信息由两个子节点提供
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
inline int L(int r)
{
return r<<;
};
inline int R(int r)
{
return r<<|;
};
inline int MID(int l,int r)
{
return (l+r)>>;
};
const int maxx = ;
struct Line
{
double l,r,h;
int f;
}line[maxx*];
struct node
{
int l,r,cover;
double len1,len2;
} tree[maxx<<];
double pos[maxx];
bool cmp(Line a,Line b){
return a.h<b.h;
}
void buildtree(int root,int l,int r)//建树
{
tree[root].l=l;
tree[root].r=r;
tree[root].len1=;
tree[root].len2=;
tree[root].cover=;
if (l==r)
{
return;
}
int mid = MID(l,r);
buildtree(L(root),l,mid);
buildtree(R(root),mid+,r);
}
int bin(double key,int low,int high)
{
while(low<=high)
{
int mid = (low+high)>>;
if (pos[mid] == key)
return mid;
else if (pos[mid] < key)
low = mid+;
else
high = mid-;
}
return -;
}
void pushup(int root)
{
int l=tree[root].l;
int r=tree[root].r;
if (tree[root].cover)tree[root].len1=pos[r+]-pos[l];
else if (l==r)tree[root].len1=;
else tree[root].len1=tree[L(root)].len1+tree[R(root)].len1; if (tree[root].cover>)tree[root].len2=tree[root].len1;
else if (l==r)tree[root].len2=;
else if (tree[root].cover==)tree[root].len2=tree[L(root)].len1+tree[R(root)].len1;
else tree[root].len2=tree[L(root)].len2+tree[R(root)].len2;
}
void update(int root,int ul,int ur,int c)
{
int l=tree[root].l;
int r=tree[root].r;
if (ul<=l && r<=ur)
{
tree[root].cover+=c;
pushup(root);
return;
}
int mid=MID(l,r);
if (ur<=mid)update(L(root),ul,ur,c);
else if (ul>mid)update(R(root),ul,ur,c);
else {
update(L(root),ul,mid,c);
update(R(root),mid+,ur,c);
}
pushup(root);
}
int main()
{
int t;
scanf("%d",&t);
int n;
while(t--){
int nums=;
scanf("%d",&n);
for (int i=;i<n;i++){
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[nums].l=x1;
line[nums].r=x2;
line[nums].h=y1;
line[nums].f=;
pos[nums++]=x1;
line[nums].l=x1;
line[nums].r=x2;
line[nums].h=y2;
line[nums].f=-;
pos[nums++]=x2;
}
sort(pos,pos+nums);
sort(line,line+nums,cmp);
int m=;
for (int i=;i<nums;i++)//去重
if (pos[i]!=pos[i-])
pos[m++]=pos[i];
buildtree(,,m-);
double ans=;
for (int i=;i<nums;i++)
{
int l=bin(line[i].l,,m-);
int r=bin(line[i].r,,m-)-;
update(,l,r,line[i].f);
ans+=tree[].len2*(line[i+].h-line[i].h);
}
printf("%.2lf\n",ans);
}
return ;
}

HDU - 1255 扫描线+离散化进阶的更多相关文章

  1. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  2. 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))

    扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...

  3. 扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]

    学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...

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

    题目地址:HDU 1255 这题跟面积并的方法非常像,仅仅只是须要再加一个变量. 刚開始我以为直接用那个变量即可,仅仅只是推断是否大于0改成推断是否大于1.可是后来发现了个问题,由于这个没有下放,没延 ...

  5. hdu 1255 覆盖的面积(线段树 面积 交) (待整理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.   In ...

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

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

  7. hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)

    了校赛,还有什么途径可以申请加入ACM校队?  覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  8. HDU 1255 覆盖的面积 (线段树+扫描线+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...

  9. 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积

    #include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...

随机推荐

  1. MyBatis笔记----MyBatis查询表全部的两种方法:XML与注解

    查询单条信息的在 http://www.cnblogs.com/tk55/p/6659285.html  已经有了 XML 修改UserMapper.xml <?xml version=&quo ...

  2. XSS攻击介绍

    一.概念 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安全漏洞, ...

  3. javascript中(function($){...})(jQuery)写法是什么意思

    这里实际上是匿名函数function(arg){...}这就定义了一个匿名函数,参数为arg 而调用函数 时,是在函数后面写上括号和实参的,由于操作符的优先级,函数本身也需要用括号,即:(functi ...

  4. MySQl ifnull()和substr()

    SUBSTR(str,pos,len) substr用来截取字符串: str 被截取的字符串 pos 开始位置 len 长度 举个例子: substr('abc',1,2)='ab' IFNULL(e ...

  5. 数据库之mysql篇(6)—— mysql常用函数函数/自定义函数

    常用函数 运算函数 我相信你都能看懂,所以以上的不再做过多解释 然后还有个,前面漏掉的between and: 意指10是否在0到20之间,如果是返回1,否则返回0 日期函数 这个要稍微注意一下参数, ...

  6. python 实现网页 自动登录

    完整代码: 1 from apscheduler.schedulers.blocking import BlockingScheduler 2 from selenium import webdriv ...

  7. 【合集】Hadoop 合集

    0. 说明 Hadoop 随笔的目录 1. HDFS 主要内容: [HDFS_1] HDFS 的概念和特性 [HDFS_2] HDFS 的 Shell 操作 [HDFS_3] HDFS 工作机制 [H ...

  8. 基于WIN8.1:新手篇→tomcat安装配置

    一.JDK配置 下载安装JDK和tomcat 打开电脑属性,高级系统设置进行环境变量配置 新建系统变量,变量值为JDK安装路径,并在系统变量path最后加上“%JAVA_HOME%\bin;%JAVA ...

  9. Photoshop怎么破解?PS怎么破解?

    Photoshop和PS这两个软件可以说是十分常见的图片处理软件了,Photoshop主要处理以像素所构成的数字图像进行图片编辑工作,而PS就更加强大了,它有很多功能,在图像.图形.文字.视频.出版等 ...

  10. 生成.project、.classpath文件

    新导出的项目如果没有.project文件,是不能导入到工具中的,需要执行maven命令生产,在进入工作空间下面,按住shift再点击鼠标右键,点击选择在此处打开命令窗口. 然后输入对应的maven命令 ...