覆盖的面积 HDU - 1255 (扫描线, 面积交)
求n个矩阵面积相交的部分,和求面积并一样,不过这里需要开两个数组保存覆盖一次和覆盖两次以上的次数的部分,还是模板,主要注意点就是pushup部分,如果我已经被两次覆盖,那我的两个数组在这个root点的宽度就可以直接算了,如果我被一次覆盖,那么我一个覆盖的部分可以直接计算,两次覆盖的部分取决于sum1数组,如果我不是一个线段,那就是0,如果我是一个线段,那么我就是由左边区间覆盖一次和右边区间覆盖一次相加得来。如果我这个区间现在没有被覆盖到,那么我的两个数组都是由各自部分的区间和得来的
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define first fi
#define second se
#define lowbit(x) (x & (-x)) typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = ;
const int maxm = ;
using namespace std; int n, m, tol, T;
struct Node{
double l, r, h;
int f;
bool operator < (Node a) const {
return h < a.h;
}
};
Node node[maxn];
double a[maxn];
int cnt[maxn << ];
double sum1[maxn << ];
double sum2[maxn << ]; void init() {
memset(a, , sizeof a);
memset(cnt, , sizeof cnt);
memset(sum1, , sizeof sum1);
memset(sum2, , sizeof sum2);
memset(node, , sizeof node);
} void pushup(int left, int right, int root) {
if(cnt[root] >= ) {
sum2[root] = sum1[root] = a[right+] - a[left];
} else if(cnt[root] == ) {
sum1[root] = a[right+] - a[left];
if(left == right) sum2[root] = ;
else sum2[root] = sum1[root << ] + sum1[root << | ];
} else {
if(left == right) sum1[root] = sum2[root] = ;
else {
sum1[root] = sum1[root << ] + sum1[root << | ];
sum2[root] = sum2[root << ] + sum2[root << | ];
}
}
} void update(int left, int right, int prel, int prer, int val, int root) {
if(prel <= left && right <= prer) {
cnt[root] += val;
pushup(left, right, root);
return ;
}
int mid = (left + right) >> ;
if(prel <= mid) update(left, mid, prel, prer, val, root << );
if(prer > mid) update(mid+, right, prel, prer, val, root << | );
pushup(left, right, root);
return ;
} int main() {
scanf("%d", &T);
while(T--) {
init();
scanf("%d", &n);
double x1, y1, x2, y2;
for(int i=; i<=n; i++) {
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
node[*i].l = node[*i-].l = x1;
node[*i].r = node[*i-].r = x2;
node[*i].h = y1, node[*i-].h = y2;
node[*i].f = , node[*i-].f = -;
a[*i] = x1, a[*i-] = x2;
}
n <<= ;
sort(node+, node++n);
sort(a+, a++n);
int nn = unique(a+, a++n) - (a+);
double ans = 0.0;
for(int i=; i<n; i++) {
int l = lower_bound(a+, a++nn, node[i].l) - a;
int r = lower_bound(a+, a++nn, node[i].r) - a;
update(, nn, l, r-, node[i].f, );
ans += sum2[] * (node[i+].h - node[i].h);
}
printf("%.2f\n", ans);
}
return ;
}
覆盖的面积 HDU - 1255 (扫描线, 面积交)的更多相关文章
- 线段树扫描线(一、Atlantis HDU - 1542(覆盖面积) 二、覆盖的面积 HDU - 1255(重叠两次的面积))
扫描线求周长: hdu1828 Picture(线段树+扫描线+矩形周长) 参考链接:https://blog.csdn.net/konghhhhh/java/article/details/7823 ...
- 面积并+扫描线 覆盖的面积 HDU - 1255
题目链接:https://cn.vjudge.net/problem/HDU-1255 题目大意:中文题目 具体思路:和上一篇的博客思路差不多,上一个题求的是面积,然后我们这个地方求的是啊覆盖两次及两 ...
- 覆盖的面积 HDU - 1255(扫描线求面积交)
题意: 就是扫描线求面积交 解析: 参考求面积并.... 就是把down的判断条件改了一下..由w > 0 改为 w > 1 同时要讨论一下 == 1 时 的情况, 所以就要用到一个临时 ...
- 覆盖的面积 HDU - 1255 (线段树-扫描线)模板提
给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1& ...
- 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积
#include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...
- 覆盖的面积(HDU 1255 线段树)
覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem D ...
- O - 覆盖的面积 - hdu 1255(求面积)
分析:求一层的面积覆盖是非常简单的事情,不过多层面积覆盖应该怎么搞???也是比较简单的事情,只需要用两个变量记录就好了,一个记录覆盖一次的,一个记录覆盖两次的,就很容易解决了 ************ ...
- HDU - 1255 扫描线+离散化进阶
这道题最开始我以为和HDU - 1542 那道题一样,只需要把cover次数改成2次即可,但是后面仔细一想,我们需要求的是覆盖次数大于等于2次的,这样的话,我们需要维护两个长度,HDU-1542 由于 ...
- 扫描线三巨头 hdu1928&&hdu 1255 && hdu 1542 [POJ 1151]
学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...
随机推荐
- JavaScript中的各种X,Y,Width,Height
在JavaScript DOM编程中,会接触很多很多很多关于浏览器的宽高,屏幕的宽高,元素的各种宽高,以及鼠标的坐标等,常常让人搞混.索性就写篇博客整理一下. case 1:鼠标的坐标 获取鼠标的坐标 ...
- 学习 yii2.0——视图之间相互包含
布局 首先创建一个布局文件simple.php,路径是在views/layout/目录下. <p>this is header</p> <?= $content ?> ...
- Jmeter之Constant Timer与constant throughput timer的区别(转)
当放置Constant Timer于两个http请求之间,那么它代表的含义是:在上一个请求发出至完成后, 开始Contant Timer指定的时间,最后再发出第二个请求.它并不是代表两个请求之间的发送 ...
- 【学亮IT手记】利用字节流复制文件
- 简单JQuery+AJAX+Servlet的计算器实现
index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- Kettle中表输出字段和字段选择
表输出: 字段选择: 注:字段选择可以输出匹配后的选中列,表输出则输出匹配后的所有列.
- scrapy全站爬取拉勾网及CrawSpider介绍
一.指定模板创建爬虫文件 命令 创建成功后的模板,把http改为https 二.CrawSpider源码介绍 1.官网介绍: 这是用于抓取常规网站的最常用的蜘蛛,因为它通过定义一组规则为跟踪链接提供了 ...
- react & youtube
react & youtube https://www.npmjs.com/package/react-youtube https://developers.google.com/youtub ...
- python数据结构与算法第四天【代码执行时间测试模块】
#!/usr/bin/env python # _*_ coding:UTF-8 _*_ from timeit import Timer def foo(): ''' 使用append方式向列表添加 ...
- scrapy 项目搭建
安装好scrapy后,开始创建项目 项目名:zhaopin 爬虫文件名:zhao 1:cmd -- scrapy startproject zhaopin 2:cd zhaopin,进入项目目 ...