HDU - 1255 扫描线+离散化进阶
这道题最开始我以为和HDU - 1542 那道题一样,只需要把cover次数改成2次即可,但是后面仔细一想,我们需要求的是覆盖次数大于等于2次的,这样的话,我们需要维护两个长度,HDU-1542 由于求的是覆盖次数大于等于一次的,我们只需要维护一个覆盖次数大于等于1的长度的len1就行,但是这道题我们要求的是覆盖两次以及两次以上的长度,这样乘以高度差,才是面积。
现在我们来想如何维护这个值?
给线段树打个标记cover,代表这个区间被完全覆盖的次数。
我们先来看看,维护覆盖一次及其以上的,应该怎么实现,我们可以从中得到启示。
- cover不为0 那么这个区间被完全覆盖。我们把整个区间长度给len1,但是我们由于经过离散化。表达式为:tree[root].len1=pos[r+1]-pos[l]
- L==R 代表跑到了叶子节点,不会有节点信息往上传,因此赋0
- 不满足上述两者,我们就可以认为,父节点的信息,又两个儿子节点的提供。
那么覆盖两次的呢?同样的分情况讨论
- cover>1 那么这个区间内被完全覆盖至少2次,值等于区间长度。
- L==R 同样的信息不能由子节点提供,赋0。
- Cover==1 那么这个区间被完全覆盖至少一,子节点覆盖次数大于等于1的次数往上pushup后,变成至少两次。
- 反之节点信息由两个子节点提供
#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 扫描线+离散化进阶的更多相关文章
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- 扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]
学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...
- HDU 1255 覆盖的面积(线段树+扫描线)
题目地址:HDU 1255 这题跟面积并的方法非常像,仅仅只是须要再加一个变量. 刚開始我以为直接用那个变量即可,仅仅只是推断是否大于0改成推断是否大于1.可是后来发现了个问题,由于这个没有下放,没延 ...
- hdu 1255 覆盖的面积(线段树 面积 交) (待整理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. In ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu 1255 覆盖的面积(求覆盖至少两次以上的面积)
了校赛,还有什么途径可以申请加入ACM校队? 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...
- 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积
#include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...
随机推荐
- springmvc复习笔记----文件上传multipartResolver
结构 web.xml <?xml version="1.0" encoding=&q ...
- shell编程—变量(三)
在shell脚本中,变量分两种,系统变量和自定义变量. 系统默认变量是系统自带的一些变量,如path为路径变量 用户自定义变量为在编写吧脚本的时候自己定义的一些变量 变量名命名规则 首个字符必须为字母 ...
- mssql sqlserver xml数据类型专题
摘要: 下文将详细讲述sql server xml数据类型的相关知识,如下所示: 实验环境: sql server 2008 R2 xml数据类型简介: mssql sqlserver xml数据类型 ...
- EOS开发语言和石墨烯技术介绍
EOS 的智能合约基于 WebAssembly(WASM) 技术执行用户生成的应用程序和代码.WASM是一项新兴的网络标准,得到了谷歌,微软,苹果等公司的广泛支持.目前,用于构建编译为WASM的应用程 ...
- Linux的notifier机制的应用
在linux内核系统中,各个模块.子系统之间是相互独立的.Linux内核可以通过通知链机制来获取由其它模块或子系统产生的它感兴趣的某些事件. notifier_block结构体在include/lin ...
- Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)
前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方式创建了两个内核线程,分别是kernel ...
- App分享之微信微博等各个社交平台的分享授权规则和常见问题
一.新浪微博分享规则 新浪微博支持分享类型: 应用内分享也就是网页分享支持: 文字,文字+图片,要分享链接需要链接添加在text里分享 客户端分享支持:文字,图片,文字+图片,图片+文字+链接 参数说 ...
- 6. svg学习笔记-路径
路径相比于多边形<polygon>元素具有更强绘图能力,<polygon>元素可以绘制任意的多边形,而路径可以绘制任意的轮廓线,是线段,曲线,圆弧的组合形式.svg中可以使用& ...
- wamp 中安装cakephp Fatal error: You must enable the intl extension to use CakePHP. in XXX
今天在wamp下安装cakephp3.x的时候,报出这么一条错误:Fatal error: You must enable the intl extension to use CakePHP. in ...
- 「2017 山东一轮集训 Day5」苹果树
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...