AcWing 247. 亚特兰蒂斯 (线段树,扫描线,离散化)

- 题意:给你\(n\)个矩形,求矩形并的面积.
- 题解:我们建立坐标轴,然后可以对矩形的横坐标进行排序,之后可以遍历这些横坐标,这个过程可以想像成是一条线从左往右扫过x坐标轴,假如这条线是第一次扫过矩形的宽(长)的话,我们就可以在\(y\)轴上对应的区间打上标记,每次枚举的面积就是当前横坐标和上次横坐标的差值乘上目前\(y\)轴上所有打上标记的区间长度\((seg[i].x-seg[i-1].x)*tr[1].len\),y轴上的区间情况我们可以通过线段树来维护.
- 代码:
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
struct Segment{
double x,y1,y2;
int k;
bool operator < (const Segment & tmp) const {
return x<tmp.x;
}
}seg[N*2];
struct Node{
int l,r;
int cnt;
double len;
}tr[8*N];
vector<double> ys;
void push_up(int u){
if(tr[u].cnt) tr[u].len=ys[tr[u].r+1]-ys[tr[u].l];
else if(tr[u].l!=tr[u].r){
tr[u].len=tr[u<<1].len+tr[u<<1|1].len;
}
else tr[u].len=0; //叶子节点并且没有标记
}
void build(int u,int l,int r){
tr[u].l=l;
tr[u].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void modify(int u,int l,int r,int k){
if(tr[u].l>=l && tr[u].r<=r){
tr[u].cnt+=k;
push_up(u);
}
else{
int mid=(tr[u].l+tr[u].r)>>1;
if(l<=mid) modify(u<<1,l,r,k);
if(r>mid) modify(u<<1|1,l,r,k);
push_up(u);
}
}
int main() {
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n;
int T=1;
while(cin>>n){
if(n==0) break;
ys.clear();
int j=0;
rep(i,0,n-1){
double x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
seg[j++]={x1,y1,y2,1};
seg[j++]={x2,y1,y2,-1};
ys.pb(y1),ys.pb(y2);
}
sort(ys.begin(),ys.end());
ys.erase(unique(ys.begin(),ys.end()),ys.end());
build(1,0,ys.size()-2);
sort(seg,seg+2*n);
double res=0;
rep(i,0,2*n-1){ //枚举横坐标 tr[1].len就表示纵坐标区间之和
if(i>0) res+=tr[1].len*(seg[i].x-seg[i-1].x);
int pos1=lower_bound(ys.begin(),ys.end(),seg[i].y1)-ys.begin();
int pos2=lower_bound(ys.begin(),ys.end(),seg[i].y2)-ys.begin();
modify(1,pos1,pos2-1,seg[i].k);
}
cout<<"Test case #"<<T++<<'\n';
cout<<"Total explored area: "<<fixed<<setprecision(2)<<res<<"\n\n";
}
return 0;
}
AcWing 247. 亚特兰蒂斯 (线段树,扫描线,离散化)的更多相关文章
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...
- POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177 题目中文翻译: 解题思路: 总体思路: 1.沿X轴离散化建树 2.按Y值从小到大排序平行与X轴的边,然后顺序处理 如果遇到矩形 ...
- HDU3642 Get The Treasury —— 求矩形交体积 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-3642 Jack knows that there is a great underground treasury in a ...
随机推荐
- OpenID协议
背景 当我们要使用一个网站的功能时,一般都需要注册想用的账号.现在的互联网应用很多,一段时间之后你会发现你注册了一堆账号密码,根本记不住. 你可能会想到所有的网站都用同一套用户名和密码,这样虽然能解决 ...
- CTFHub - Web(六)
命令注入: 1.进入页面,测试127.0.0.1, 关键代码: <?php $res = FALSE; if (isset($_GET['ip']) && $_GET['ip'] ...
- oracle优化求生指南脚本记录
1.查找未使用索引 /* Formatted on 2020/5/12 下午 03:32:39 (QP5 v5.163.1008.3004) */ WITH IN_PLAN_OBJECTS AS (S ...
- 3A的限流芯片PW1503
PW1503是超低RDS(ON)开关,具有可编程的电流限制,以保护电源于过电流和短路情况.它具有超温保护以及反向闭锁功能. PW1503采用薄型(1毫米)5针薄型SOT封装,提供可调版本. 特征 ...
- 使用存储过程在mysql中批量插入数据
一.在mysql数据库中创建一张表test DROP TABLE IF EXISTS `test`; CREATE TABLE `test` ( `id` INT (11), `name` VARCH ...
- .NET Core使用Source Link提高源代码调试体验和生产效率
前言: 在我们日常开发过程中常常会使用到很多其他封装好的第三方中间件(NuGet依赖项).类库或者是.NET框架中自带的库.但是当你想要对这些类库的方法设置断点调试,然后发现无法F11(逐语句)调试进 ...
- ubuntu更新下载软件卡住0% [Connecting to archive.ubuntu.com (2001:67c:1360:8001::23)]
一台ubuntu系统,查看硬件和配置环境的时候发现下载卡住了 根据提示就是有ipv6地址,系统也是配置了ipv6地址的.海外机器,而且可以ping通域名 最佳解决方案 我想出了如何让apt-get再次 ...
- 干货 | 质量保障新手段,携程回归测试平台实践 原创 Sedro 携程技术 2021-01-21
干货 | 质量保障新手段,携程回归测试平台实践 原创 Sedro 携程技术 2021-01-21
- 一次I/O问题引发的P0重大故障[改版重推] 原创 二马读书 二马读书 8月16日 这是前段时间发的一篇文章,很多读者反馈,文章没有揭示故障发生的详细
一次I/O问题引发的P0重大故障[改版重推] 原创 二马读书 二马读书 8月16日 这是前段时间发的一篇文章,很多读者反馈,文章没有揭示故障发生的详细
- Dubbo 总结:关于 Dubbo 的重要知识点
一 重要的概念 1.1 什么是 Dubbo? Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能.轻量级的开源Java RPC 框架,它提供了三大核心能力:面向接口的远 ...