当前位置: 首页 > wzjs >正文

给公司做网站多钱奇葩网站100个

给公司做网站多钱,奇葩网站100个,做图片网站会侵权吗,0731网站https://www.luogu.com.cn/problem/P5490 题目描述 求 n n n 个四边平行于坐标轴的矩形的面积并。 输入格式 第一行一个正整数 n n n。 接下来 n n n 行每行四个非负整数 x 1 , y 1 , x 2 , y 2 x_1, y_1, x_2, y_2 x1​,y1​,x2​,y2​,表示一个矩形的四个…

https://www.luogu.com.cn/problem/P5490

题目描述

n n n 个四边平行于坐标轴的矩形的面积并。

输入格式

第一行一个正整数 n n n

接下来 n n n 行每行四个非负整数 x 1 , y 1 , x 2 , y 2 x_1, y_1, x_2, y_2 x1,y1,x2,y2,表示一个矩形的四个端点坐标为 ( x 1 , y 1 ) , ( x 1 , y 2 ) , ( x 2 , y 2 ) , ( x 2 , y 1 ) (x_1, y_1),(x_1, y_2),(x_2, y_2),(x_2, y_1) (x1,y1),(x1,y2),(x2,y2),(x2,y1)

输出格式

一行一个正整数,表示 n n n 个矩形的并集覆盖的总面积。

输入输出样例 #1

输入 #1

2
100 100 200 200
150 150 250 255

输出 #1

18000

说明/提示

对于 20 % 20\% 20% 的数据, 1 ≤ n ≤ 1000 1 \le n \le 1000 1n1000
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 10 5 1 \le n \le {10}^5 1n105 0 ≤ x 1 < x 2 ≤ 10 9 0 \le x_1 < x_2 \le {10}^9 0x1<x2109 0 ≤ y 1 < y 2 ≤ 10 9 0 \le y_1 < y_2 \le {10}^9 0y1<y2109

🚀 C++ 代码实现

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;struct Event {int x, y1, y2, type; // x 坐标, y 起点, y 终点, type=1(加入), type=-1(删除)Event(int x, int y1, int y2, int type) : x(x), y1(y1), y2(y2), type(type) {}
};struct SegmentTree {// y 轴区间被覆盖次数机覆盖长度vector<int> cnt, len;// 存储离散化后的 y 坐标值,用于映射 y 轴上的真实值到线段树的索引vector<int> y_coords;SegmentTree(int size) {cnt.resize(size * 4);len.resize(size * 4);}void build(int l, int r, int idx) {cnt[idx] = len[idx] = 0;if (l + 1 == r) return;int mid = (l + r) / 2;build(l, mid, idx * 2);build(mid, r, idx * 2 + 1);}void update(int jobl, int jobr, int val, int l, int r, int idx) {if (jobl >= r || jobr <= l) return;if (jobl <= l && r <= jobr) {cnt[idx] += val;} else {int mid = (l + r) / 2;update(jobl, jobr, val, l, mid, idx * 2);update(jobl, jobr, val, mid, r, idx * 2 + 1);}// 计算当前区间的 y 方向被覆盖的长度if (cnt[idx] > 0) {len[idx] = y_coords[r] - y_coords[l];  // 计算该段区间长度} else {len[idx] = (l + 1 == r) ? 0 : (len[idx * 2] + len[idx * 2 + 1]);  // 合并子区间}}
};int main() {int n;cin >> n;vector<Event> events;vector<int> y_coords;// 读取矩形数据for (int i = 0; i < n; i++) {int x1, y1, x2, y2;cin >> x1 >> y1 >> x2 >> y2;events.emplace_back(x1, y1, y2, 1);  // 左边界events.emplace_back(x2, y1, y2, -1); // 右边界y_coords.push_back(y1);y_coords.push_back(y2);}// 对 y 坐标进行离散化sort(y_coords.begin(), y_coords.end());y_coords.erase(unique(y_coords.begin(), y_coords.end()), y_coords.end());// 给事件按照 x 轴排序sort(events.begin(), events.end(), [](const Event &a, const Event &b) {return a.x < b.x;});// 初始化线段树SegmentTree segTree(y_coords.size());segTree.y_coords = y_coords;segTree.build(0, y_coords.size() - 1, 1);long long area = 0;for (size_t i = 0; i < events.size() - 1; i++) {int x = events[i].x;int y1 = lower_bound(y_coords.begin(), y_coords.end(), events[i].y1) - y_coords.begin();int y2 = lower_bound(y_coords.begin(), y_coords.end(), events[i].y2) - y_coords.begin();segTree.update(y1, y2, events[i].type, 0, y_coords.size() - 1, 1);// 计算面积增量int dx = events[i + 1].x - x;area += 1LL * dx * segTree.len[1];  // 累加当前 x 范围的面积}cout << area << endl;return 0;
}

🌟 解法思路:扫描线 + 线段树

核心思想:

  1. 转换为扫描线问题

    • 把每个矩形拆成两条竖直边(左边界 + 右边界)。
    • 每条边记录 x 坐标、y 区间以及是左边界(加入)还是右边界(删除)
  2. x 坐标排序

    • 依次处理 x 变化的位置,维护 y 方向的覆盖情况。
  3. 使用线段树维护 y 方向的覆盖长度

    • 统计当前 x 坐标下 y 方向被覆盖的总长度。
    • x 变化时,用 dx * covered_length 计算新增的面积。

📌 代码解析

  1. 读取输入并创建事件

    • 每个矩形 (x1, y1, x2, y2) 被拆成两个事件:
      • 左边界(x1, y1, y2, +1)
      • 右边界(x2, y1, y2, -1)
  2. 离散化 y

    • y 轴可能范围很大,使用排序+去重y 压缩成 [0, m-1] 范围。
  3. 排序事件

    • 按照 x 轴排序,保证扫描顺序是从左到右。
  4. 扫描线遍历

    • 遍历 x 方向的边界事件,更新 y 方向的覆盖长度。
    • 计算当前 x 范围的面积增量 dx * covered_length
  5. 线段树维护 y 方向覆盖情况

    • update(y1, y2, type) 更新 cnt 计数。
    • len[1] 存储 y 方向被覆盖的总长度。

📊 复杂度分析

  • 事件排序 O ( N log ⁡ N ) O(N \log N) O(NlogN)
  • 线段树更新 O ( N log ⁡ N ) O(N \log N) O(NlogN)
  • 总时间复杂度 O ( N log ⁡ N ) O(N \log N) O(NlogN)

✅ 适用场景

  • 计算多个矩形的面积并
  • 计算建筑投影面积
  • 计算不规则区间合并

📌 该方法适用于 N ≤ 10^5 的情况,效率极高!🚀


线段树的构建过程中,我们通常将一个区间 [l, r] 拆分,直到无法继续拆分为止。
在很多常见的线段树应用(如单点更新、区间查询)中,叶子节点往往是 l == r,但是在扫描线+线段树这种应用场景下,我们的离散化 y 坐标并不连续,因此叶子节点的定义有所不同l + 1 == r 才是叶子节点,而不是 l == r


🌟 为什么 l + 1 == r 才是叶子节点?

离散化的线段树是基于区间而不是单个点。

  • 常规线段树(连续区间)

    • 例如求区间最小值、区间和,通常是 l == r 作为叶子节点。
    • 但在这里,我们是计算“区间长度”,所以叶子节点应该是最小单位的区间 [y_coords[l], y_coords[r]],而不是单个点。
  • 离散化线段树(区间合并)

    • 叶子节点应该是最小的 y 轴区间,而 l == r 只表示单个坐标,不是一个“区间”。
    • l + 1 == r,意味着 y_coords[l]y_coords[r] 之间已经没有更多的离散坐标,可以认为它们形成了最小单位的“区间”,无法再继续细分,因此它是叶子节点。

🔹 详细举例

1️⃣ 假设 y_coords = {2, 5, 10, 15}

离散化后的 y_coords 索引:

y离散索引
20
51
102
153

表示的区间:

区间 [0,1] 表示 y = [2, 5]
区间 [1,2] 表示 y = [5, 10]
区间 [2,3] 表示 y = [10, 15]

2️⃣ 线段树的构造

构建线段树时,我们递归拆分区间 [0,3]

          [0,3]/     \[0,2]   [2,3]/     \[0,1]   [1,2]

在这棵树中:

  1. [0,1] 表示 [2,5],是叶子节点(因为 0+1 == 1
  2. [1,2] 表示 [5,10],是叶子节点(因为 1+1 == 2
  3. [2,3] 表示 [10,15],是叶子节点(因为 2+1 == 3

3️⃣ 为什么 l + 1 == r 作为叶子节点,而 l == r 不行?

如果 l == r 作为叶子节点,那就会出现 l = 0, r = 0 这种情况,这样的区间没有物理意义,因为:

  • y_coords[0] = 2 只是一个点,并不能表示一个范围。
  • y_coords[0]y_coords[1] ([2,5]) 形成了一个“区间”,才有意义。

所以,叶子节点的最小单位应该是 [y_coords[l], y_coords[r]],而不是单个点


✅ 结论

方式叶子节点定义适用情况是否适用于扫描线+线段树
l == r单个点适用于连续值(如 RMQ、区间和)❌ 不适用于离散区间
l + 1 == r一个离散区间适用于离散化的线段树(扫描线)✅ 适用

📌 代码示例

if (l + 1 == r) { // 叶子节点len[idx] = 0;  // 初始状态下没有被覆盖
} else { // 非叶子节点,合并左右子树len[idx] = len[idx * 2] + len[idx * 2 + 1];
}

🎯 总结

  • 线段树的叶子节点是最小单位的“区间”而不是单点,所以 l + 1 == r 作为叶子节点。
  • 常规线段树 l == r 适用于单点查询,但扫描线 + 线段树需要处理区间,所以 l + 1 == r 作为叶子节点
  • 这样,我们才能用 y_coords[r] - y_coords[l] 计算被覆盖的区间长度,否则 l == r 没有意义。

🚀 这样就能理解为什么 l + 1 == r 是叶子节点,而 l == r 不行了!

扫描线相关练习题目

  • 218. 天际线问题
  • P1904 天际线
http://www.dtcms.com/wzjs/223938.html

相关文章:

  • 网站设计与开发实验报告新闻发布会新闻通稿
  • 珠海学网站开发产品推广词
  • 网站建设项目分析报告需要优化的网站有哪些
  • 电子商务网站建设评估的指标有哪些?手机百度app
  • 装修哪个平台最好郑州seo顾问培训
  • 天津建网站的公司排名推广网站
  • jsp做网站用到什么技术山西网络营销外包
  • 网站建设服务费下什么科目百度官网网站登录
  • 做网站js是什么合理使用说明
  • 网站后台程序开发教程武汉seo结算
  • 阿里巴巴网站怎么做推广方案网络推广外包搜索手机蛙软件
  • 怎么用java 做网站seo免费诊断联系方式
  • 网站建设购买google海外版
  • 网站建设唐山百度快照入口官网
  • 做网站骗局免费做网站软件
  • 无锡微信手机网站制作餐饮营销策划方案
  • 一个ip两个网站怎么做网站ui设计
  • 广州网站建设案例绍兴百度seo排名
  • dedecms 网站搬迁 模板路径错误南宁优化网站收费
  • 建设网站收费标准谷歌官方app下载
  • 上海大型网站制作公厦门网站建设公司名单
  • 网址大全汽车之家汕头seo计费管理
  • 响应式布局网站开发北京发生大事了
  • 网站开发教育类近期新闻事件
  • 网站建设公司业务人员岗位职责工具大全
  • 招聘网站怎么做推广做了5天游戏推广被抓了
  • 本网站建设在美国网络零售的优势有哪些
  • 怎样向搜索引擎提交网站银川网站seo
  • 做公益网站的说明seo助理
  • 手机微信网站怎么做的好seo排名赚app下载