POJ 1151 Atlantis(扫描线)

POJ 1151 - Atlantis 线段树+扫描线.. 离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值...    扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行于x轴的边..但是真正在做的时候..不需要完全模拟这个过程..扫描线的做法是从最下面的边开始扫到最上面的边.    线段树: 本题用于动态维护扫描线在往上走时..x哪些区域是有合法面积的.. 阅读详情

POJ 1151 Atlantis

Description
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.
Input
The input consists of several test cases. Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.
The input file is terminated by a line containing a single 0. Don’t process it.
Output
For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.
Output a blank line after each test case.
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00

AC代码1

/*
【AgOHの算法胡扯】扫描线算法 视频中的方法——魔改线段树
https://www.bilibili.com/video/av63999460
*/
#include<cstdio>
#include<algorithm>

const int N = 210;

double v[N];

struct Line {
    double y, x1, x2;
    int state;

    Line() {}

    Line(double y, double x1, double x2, int state) : y(y), x1(x1), x2(x2), state(state) {}

    bool operator<(const Line &oth) { return y < oth.y; }
} line[N];

struct Node {
    double l, r, len;
    int cover;
} seg[N << 3];

inline int ls(int k) { return k << 1; }

inline int rs(int k) { return k << 1 | 1; }

inline void PushUp(int k) {
    double l = seg[k].l, r = seg[k].r;
    if (seg[k].cover) seg[k].len = seg[k].r - seg[k].l;
    else seg[k].len = seg[ls(k)].len + seg[rs(k)].len;
}

void BuildTree(int l, int r, int k = 1) {
    seg[k].l = v[l], seg[k].r = v[r];
    seg[k].len = 0.0, seg[k].cover = 0;
    if (r - l <= 1) return;
    int m = (l + r) >> 1;
    BuildTree(l, m, ls(k));
    BuildTree(m, r, rs(k));	//这里的左右区间之间没有间隔,即[l,r]分成了 [l,m]和[m,r]两部分
}

void modify(double L, double R, int state, int k = 1) {
    double l = seg[k].l, r = seg[k].r;
    if (L <= l && r <= R) {
        seg[k].cover += state;
        PushUp(k);
        return;
    }
    if (L < seg[ls(k)].r) modify(L, R, state, ls(k));
    if (R > seg[rs(k)].l) modify(L, R, state, rs(k));
    PushUp(k);
}

int main() {
    int n, T = 0;
    double a, b, c, d;
    while (scanf("%d", &n) == 1 && n != 0) {
        for (int i = 1; i <= n; ++i) {
            scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
            v[i] = a, v[n + i] = c;
            line[i] = Line(b, a, c, 1), line[n + i] = Line(d, a, c, -1);
        }
        n <<= 1;
        std::sort(v + 1, v + n + 1);
        std::sort(line + 1, line + n + 1);
        BuildTree(1, n);
        double ans = 0.0;
        for (int i = 1; i <= n; ++i) {
            ans += seg[1].len * (line[i].y - line[i - 1].y);
            modify(line[i].x1, line[i].x2, line[i].state);
        }
        printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++T, ans);
    }
    return 0;
}

AC代码2

#include<cstdio>
#include<algorithm>

using namespace std;
const int N = 222;
double X[N];

struct node {
    double l, r, h;
    int d;

    node() {}

    node(double a, double b, double c, int d) : l(a), r(b), h(c), d(d) {}

    bool operator<(const node &b) const {
        return h < b.h;
    }
} nodes[N];

int cnt[N * 4];
double sum[N * 4];

void PushDown(int i, int l, int r) {
    int m = (l + r) / 2;
    if (cnt[i] != -1) {
        cnt[i * 2] = cnt[i * 2 + 1] = cnt[i];
        sum[i * 2] = (cnt[i] ? (X[m + 1] - X[l]) : 0);
        sum[i * 2 + 1] = (cnt[i] ? (X[r + 1] - X[m + 1]) : 0);
    }
}

void PushUp(int i, int l, int r) {
    if (cnt[i * 2] == -1 || cnt[i * 2 + 1] == -1)
        cnt[i] = -1;
    else if (cnt[i * 2] != cnt[i * 2 + 1])
        cnt[i] = -1;
    else
        cnt[i] = cnt[i * 2];
    sum[i] = sum[i * 2] + sum[i * 2 + 1];
}

void build(int i, int l, int r) {
    if (l == r) {
        cnt[i] = 0;
        sum[i] = 0.0;
        return;
    }
    int m = (l + r) / 2;
    build(i*2,l,m);
    build(i*2+1,m+1,r);	//这里是正常的线段树做法,代码中的[l,r]实际上是表示图中的[l,r+1]
    PushUp(i, l, r);
}

void update(int ql, int qr, int v, int i, int l, int r) {
    if (ql <= l && r <= qr) {
        if (cnt[i] != -1) {
            cnt[i] += v;
            sum[i] = (cnt[i] ? (X[r + 1] - X[l]) : 0);
            return;
        }
    }
    PushDown(i, l, r);
    int m = (l + r) / 2;
    if (ql <= m) update(ql, qr, v, i*2,l,m);
    if (m < qr) update(ql, qr, v, i*2+1,m+1,r);
    PushUp(i, l, r);
}

int bin(double key, int n, double d[]) {
    int l = 1, r = n;
    while (r >= l) {
        int m = (r + l) / 2;
        if (d[m] == key)
            return m;
        else if (d[m] > key)
            r = m - 1;
        else
            l = m + 1;
    }
    return -1;
}

int main() {
    int q;
    int T = 0;
    while (scanf("%d", &q) == 1 && q) {
        int n = 0, m = 0;
        for (int i = 1; i <= q; i++) {
            double x1, y1, x2, y2;
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            X[++n] = x1;
            nodes[++m] = node(x1, x2, y1, 1);
            X[++n] = x2;
            nodes[++m] = node(x1, x2, y2, -1);
        }
        sort(X + 1, X + n + 1);
        sort(nodes + 1, nodes + m + 1);
        int k = 1;//共k个不同的x坐标,组成了k-1个不同的区域
        for (int i = 2; i <= n; i++)
            if (X[i] != X[i - 1]) X[++k] = X[i];
        build(1, 1, k - 1);//少了build就WA
        double ret = 0.0;//最终面积
        for (int i = 1; i < m; i++) {
            int l = bin(nodes[i].l, k, X);
            int r = bin(nodes[i].r, k, X) - 1;
            if (l <= r) update(l, r, nodes[i].d, 1,1,k-1);
            ret += sum[1] * (nodes[i + 1].h - nodes[i].h);
        }
        printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++T, ret);
    }
    return 0;
}
Open-Sora代码详细解读(2):时空3D VAE 目前开源的DiT视频生成模型不是很多,Open-Sora是开发者生态最好的一个,涵盖了DiT、时空DiT、3D VAE、Rectified Flow、因果卷积等Diffusion视频生成的经典知识点。本篇博客从Open-Sora的代码出发,深入解读背后的原理。 阅读详情

相关推荐

Lattice FPGA 开发工具Diamond使用流程总结——工具使用

本文介绍了一般的Diamond开发流程,包括工程创建、文件输入、IP使用、约束、管脚分配、和布线布局等流程

weixin_41895751的博客 2万+

POJ1151 Atlantis(扫描线、线段树)

Atlantis Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your fri

m0_51864047的博客 297

Bladed风电仿真软件新手必看:从界面操作到功率曲线计算的完整指南

本文为风电工程师提供Bladed仿真软件的完整入门指南,涵盖界面操作、功率曲线计算及动态仿真等核心功能。通过实战技巧和常见问题解决方案,帮助新手快速掌握这款全球领先的风电机组仿真工具,提升风电项目开发效率。

weixin_30839881的博客 102

Atlantis--POJ1151---线段树扫描线图文详解+模板

Describtion: There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps ...

Bearing in mind forever! 672

Skyworks SKY85331-11的Wi-Fi 6 (802.11ax)标准 2.4G 高功率WLAN前端模块解决方案

SKY85331-11是高度集成的2 GHz前端模块(FEM)包含2 GHz单刀双掷(SPDT)发送/接收(T / R)开关,2 GHz低噪声放大器(LNA)带旁路和一个2 GHz功率放大器(PA),用于大功率802.11ax应用程序和系统LNA和PA禁用功能可确保低漏电流 关闭模式。 包括一个集成的功率检测器以提供系统内的闭环功率控制。该设备提供Small (24-pin, 3 x 5 mm) (LGA)封装。 图1.引脚配置和封装如图所示 图2.信号引脚分配和功能引脚描述 图...

zhangbao19890622的博客 4505

避开地图定位的坑:手把手教你处理GCJ-02和WGS-84坐标转换(2023最新版)

本文深入解析了GCJ-02与WGS-84坐标系转换的核心原理与常见误区,提供了详细的代码实现与精度控制方法。针对地图定位开发中的实际痛点,文章重点阐述了如何通过迭代逼近法实现高精度坐标转换,并给出了误差测试与业务场景下的工程实践指南,帮助开发者有效规避定位漂移等问题。

lstm7chronicler的博客 1170

POJ 1151 矩形切割

【题目】http://poj.org/problem?id=1151 【题意】求矩形面积并。 【解题方法】可以线段树扫描线,当然这里我是来试一试矩形切割的。 【AC 代码】在POJ和HDU均测试通过。 #include #include #include #include using namespace std; const int N = 105; struct no

I good vegetable a! 660

POJ 1151 (线段树、离散化、扫描分割)

题意: 有n个矩形,求出总面积(面积并),矩形之间有可能重合。 思路: 这道题的目的是求出面积的并,因为有重合的部分所以常规方式不行。 扫描线法:想像一条平行于y轴的线,从x最小开始向右扫描,扫描出的面积就是总 面积。 看起来很简单,实现起来是用到了线段树维护y的长度,长度怎么维护? 将平行于y轴的线段依次插入线段树中,线段树保存当前的len。 离散化y[]的目

Since_natural_ran 629

addr2line解析不出来行号的解决方式(汇编解析高阶版)

摘要:本文针对AEC crash问题中addr2line无法解析行号的情况,通过llvm-addr2line和反汇编分析,定位到CamX::AECBEStats17::AdjustROIParams函数中的乘法溢出问题。关键发现包括: 常规addr2line只能解析到函数名但无具体行号 llvm-addr2line解析出多个可能溢出点(行196/204/211/218/270/271) 反汇编显示6个条件分支跳转到溢出处理函数 源码分析确认这些位置均存在乘法运算 最终通过汇编级调试工具成功定位UBsan报告

168

基于simulink的预测电流控制策略的三相逆变器仿真

本文详细介绍了在Simulink中实现基于预测电流控制策略的三相逆变器仿真方法。主要内容包括:准备工作(安装必要软件及工具箱)、构建三相逆变器基础模型、设计预测电流控制器(包含状态空间建模和控制器设计)、实现控制逻辑、添加示波器观察输出、配置仿真参数以及运行仿真分析结果。通过MATLAB代码示例和Simulink模块说明,展示了如何选择最优开关状态来最小化电流误差。该仿真方法为研究快速响应、高精度的逆变器控制提供了实用工具,但需注意实际应用中可能需要的调试工作。

amy_mhd的博客 276

Atlantis POJ1151(N^2算法)

题目大意 给你n个矩形,让你求所有矩形覆盖的总面积,重叠的地方只算一次 输入格式 输入的第一行包含一个整数n,表示可得到的地图数目。 以下n行,每行描述一张地图。每行包含4个整数x1,y1,x2和y2(0≤x1<x2≤30000,0≤y1<y2≤30000)。数值(x1,y1)和(x2,y2)是坐标,分别表示绘制区域的左下角和右上角坐标。每张地图是矩形的,并且它的边是平行于x坐标轴或y坐标轴的。 ...

hwdn3000的博客 351

[VCS]门级仿真及SDF反标

摘要:门级仿真在STA工具普及后仍是验证的重要环节,主要用于检查SDC完备性、异步电路时序、网表完整性及为功耗分析提供波形。门级仿真分为不带时序反标的前仿和带SDF反标的后仿,后仿需加载SDF文件提供精确延时信息。VCS提供多种仿真选项控制时序检查行为,SDF反标可通过命令或系统函数实现。后仿需特别注意关闭notimingcheck选项以确保时序检查有效性,并建议检查SDF反标报告和波形验证延时一致性。

元直的博客 9792

【POJ 1151】 Atlantis(离散化+扫描线)

【POJ 1151】 Atlantis(离散化+扫描线) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20223   Accepted: 7634 Description There are several ancient Greek texts that

ACMer' 1302

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

POJ 1151 Atlantis(扫描线求面积)

POJ 1151 Atlantis(扫描线求面积)

Insist111 347

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

POJ1151 Atlantis 【扫描线】

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16882   Accepted: 6435 Description There are several ancient Greek texts that contain descriptions

长风的专栏 2287

POJ 1151 Atlantis(扫描线法、线段树、离散化)

POJ 1151 Atlantis(扫描线法、线段树、离散化) 蓝书线段树练习题 POJ 1151 Atlantis 题意:给定n个矩形的左下、右上的两个坐标点(x,y)(x,y)(x,y),求他们的面积并(总面积) 数据范围:n:100、x/y:1e5n:100、x/y:1e5n:100、x/y:1e5 思路:现在好困明天再写^^ LL n; struct SegmentTree{ int ...

手扶拖拉机如何改装四驱 181

poj 1151 Atlantis 扫描线

题目:poj1151 建议先参考参考别的扫描线文档。 考虑这样一些矩形: 拿一根扫描线从左往右扫,扫描线被矩形覆盖的长度会变化当扫过矩形的左右边界时。 我们就剥离出来左右边界。我们把所有的 \(y\) 值都保存下来离散化。 我们拿线段树维护扫描线。线段树结点应保存从第几个 \(y\) 开始到第几个 \(y\) 结束,有多少个区间是有覆盖的。因此,维护 \(l\) 个到 \(r\) 个的...

dianjiaxian1205的博客 168

POJ 1151 Atlantis 求矩阵面积并 扫描线 详解

题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092.html 对于一个矩阵,我们只关心他的上下底边。线段树维护的是当前有哪些区间是被线段覆盖的(即被线段覆盖的区间长度) 我们从上往下扫,则对于任意一条(如15,10)  我们会计算(2

九野的博客 2623

POJ 1151 Atlantis【扫描线】

题目链接 题目描述: 扫描线模板题:给一些矩形的左下和右上坐标,求这些矩形面积的并集。 题解: 扫描线朴素算法O(n^2): 设想有这样一条竖直(或水平)无限长的线,从左往右扫,扫的时候逐渐累加面积。 我们将每个矩形用一个四元组<x, y1, y2, k>表示,即表示矩形的两条对边,设矩形的左边那条边k = 1,右边那条边k = -1。设某一时刻扫描线与矩形并集最外面的两个交点之间的距离为len,则存在一个区间[x1, x2]上两个交点的距离一直是len,扫描线从x1->x2这段累加的

weixin_44258590的博客 273

POJ-1151-Atlantis-求矩形面积并(线段树+扫描线)

http://poj.org/problem?id=1151 给你n个矩形,求面积并,点范围大,需要离散化 按照套路,先离散化,然后从下往上扫描,每次更新线段树区间,累加面积和。 #include #include #include #include #include #include #include #include #include #

缺氧 863

【POJ1151】Atlantis(线段树,扫描线)

【POJ1151】Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) 这样只需要求出每次和\(x\)轴覆盖的长度 就可以两两相乘,求出面积 最后累计和就行啦 #include<iostream> #include<cstdio> #include...

weixin_30672019的博客 90

POJ 1151 Atlantis 线段树扫描线

$ \Rightarrow $ 戳我进POJ原题 Atlantis Time Limit: 1000MS $ \quad $ Memory Limit: 10000K   Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. So...

ayf1988的博客 240

POJ 1151 Atlantis(扫描线)

题目原链接:http://poj.org/problem?id=1151 题目中文翻译: POJ 1151 Atlantis Time Limit:1000MS Memory Limit:10000K Total Submissions:25769 Accepted:9477 Des...

anshuo0835的博客 184

Atlantis 【POJ - 1151】【扫描线模板讲解】

题目链接   是第二次写这道题了,但是也加深了我对扫描线的印象了,具体什么是扫描线,我们就如是讲讲吧:   扫描线就是为了方便处理有重的区间面积的方式,我们通过线段树的方式去优化它,可以做到更少的时间复杂度,对于一个二维平面,我们用一个平行于Y轴的线向上递推,每次可以取到一次距离,并且Y不重叠。那么扫描线之间的Y轴差就是高度,我们在乘以它所得到的宽度X轴的覆盖,那么不断这样累加,就能得到完全的...

既然弱小,就只顾变强就是了 563

poj 1151 Atlantis (线段树扫描线)

题意:给你n个矩形的左下角和右上角的坐标,现在问你这个复合矩形的总面积思路:这就是线段树扫描线的裸题,扫描线就是在你的复合矩形上面加上一条虚拟的线,其中有两种一种是从左往右的扫描线,一种是从下到上的,这里我写的是从下到上的扫描线,先上图把&lt;来源见水印&gt;我们现在来讲一下,首先我们将横坐标离散,之后将离散后的坐标映射到线段树上,之后按照矩形和纵坐标从小到大排序(保证他是从最下往最上扫)当我...

wjmwsgj的博客 255
上一篇: 洛谷 P5490【模板】扫描线
下一篇: 洛谷 P3396 哈希冲突(根号算法 分块)
LZH0217
博客等级 码龄8年 36粉丝 206原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值