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

lovefort表白网站制作女生做网站运营好吗

lovefort表白网站制作,女生做网站运营好吗,建网站教程视频下载,网站建设第二年费用目录 一、线段树(Segment Tree) 基本概念 结构 操作 示例代码 二、扫描线(Sweep Line) 基本概念 应用场景 示例代码(矩形面积并集) 三、总结 一、线段树(Segment Tree) 基本…

目录

一、线段树(Segment Tree)

基本概念

结构

操作

示例代码

二、扫描线(Sweep Line)

基本概念

应用场景

示例代码(矩形面积并集)

三、总结


一、线段树(Segment Tree)

基本概念

        线段树是一种用于处理区间查询和更新操作的数据结构,常用于解决区间最值、区间和等问题。它将一个区间划分为若干个子区间,每个子区间对应树中的一个节点。

结构

  • 叶子节点:代表数组中的单个元素。

  • 内部节点:代表数组中的某个区间,通常是其子节点的并集。

操作

  1. 构建(Build):从数组构建线段树,时间复杂度为 O(n)O(n)。

  2. 查询(Query):查询某个区间的信息(如最小值、最大值、和等),时间复杂度为 O(log⁡n)O(logn)。

  3. 更新(Update):更新数组中的某个元素,并相应地更新线段树,时间复杂度为 O(log⁡n)O(logn)。

示例代码

#include <vector>  // 引入向量容器,用于动态数组
#include <algorithm>  // 引入算法库,提供常用算法(如排序)class SegmentTree {
private:std::vector<int> tree;  // 线段树的数组表示int n;  // 原始数组的大小// 构建线段树的递归函数void build(const std::vector<int>& arr, int node, int start, int end) {if (start == end) {  // 如果当前区间只有一个元素tree[node] = arr[start];  // 直接将数组值赋给叶子节点} else {int mid = (start + end) / 2;  // 计算区间的中点build(arr, 2 * node + 1, start, mid);  // 递归构建左子树build(arr, 2 * node + 2, mid + 1, end);  // 递归构建右子树tree[node] = tree[2 * node + 1] + tree[2 * node + 2];  // 当前节点的值为左右子节点的和}}// 查询区间和的递归函数int query(int node, int start, int end, int l, int r) {if (r < start || end < l) {  // 如果查询区间与当前区间无交集return 0;  // 返回0,表示无贡献}if (l <= start && end <= r) {  // 如果当前区间完全包含在查询区间内return tree[node];  // 返回当前节点的值}int mid = (start + end) / 2;  // 计算区间的中点// 递归查询左右子树,并将结果相加return query(2 * node + 1, start, mid, l, r) + query(2 * node + 2, mid + 1, end, l, r);}// 更新数组中某个元素的递归函数void update(int node, int start, int end, int idx, int val) {if (start == end) {  // 如果当前区间只有一个元素tree[node] = val;  // 直接更新叶子节点的值} else {int mid = (start + end) / 2;  // 计算区间的中点if (idx <= mid) {  // 如果目标位置在左子树update(2 * node + 1, start, mid, idx, val);  // 递归更新左子树} else {  // 如果目标位置在右子树update(2 * node + 2, mid + 1, end, idx, val);  // 递归更新右子树}tree[node] = tree[2 * node + 1] + tree[2 * node + 2];  // 更新当前节点的值为左右子节点的和}}public:// 构造函数,初始化线段树SegmentTree(const std::vector<int>& arr) {n = arr.size();  // 获取原始数组的大小tree.resize(4 * n);  // 为线段树分配空间,通常为4倍数组大小build(arr, 0, 0, n - 1);  // 构建线段树}// 查询区间和的公共接口int query(int l, int r) {return query(0, 0, n - 1, l, r);  // 调用私有查询函数}// 更新数组中某个元素的公共接口void update(int idx, int val) {update(0, 0, n - 1, idx, val);  // 调用私有更新函数}
};

二、扫描线(Sweep Line)

基本概念

        扫描线算法是一种用于处理几何问题的算法,通常用于计算平面中多个矩形的并集面积、线段交点等问题。其核心思想是通过一条虚拟的线(通常是垂直于x轴或y轴的线)在平面上扫描,并在扫描过程中处理与线相交的几何对象。

应用场景

  • 矩形面积并集:计算多个矩形的总面积。

  • 线段交点:找出所有线段的交点。

  • 多边形面积:计算多边形的面积。

示例代码(矩形面积并集)

#include <vector>  // 引入向量容器,用于动态数组
#include <algorithm>  // 引入算法库,提供常用算法(如排序)
#include <set>  // 引入集合容器,用于存储和管理活动的区间// 定义事件结构体,表示矩形的开始或结束事件
struct Event {int x, y1, y2;  // x坐标,y1和y2表示矩形的垂直区间bool isStart;  // 标记事件是矩形的开始还是结束Event(int x, int y1, int y2, bool isStart) : x(x), y1(y1), y2(y2), isStart(isStart) {}
};// 比较函数,用于对事件按x坐标排序
bool compareEvents(const Event& a, const Event& b) {return a.x < b.x;  // 按x坐标升序排列
}// 计算矩形面积并集的函数
int calculateArea(const std::vector<std::vector<int>>& rectangles) {std::vector<Event> events;  // 存储所有事件(矩形的开始和结束)for (const auto& rect : rectangles) {// 添加矩形的开始事件(左边界)events.emplace_back(rect[0], rect[1], rect[3], true);// 添加矩形的结束事件(右边界)events.emplace_back(rect[2], rect[1], rect[3], false);}// 对所有事件按x坐标排序std::sort(events.begin(), events.end(), compareEvents);std::multiset<std::pair<int, int>> activeIntervals;  // 存储当前活动的垂直区间int prevX = 0;  // 前一个事件的x坐标int totalArea = 0;  // 总面积// 遍历所有事件for (const auto& event : events) {int currentX = event.x;  // 当前事件的x坐标if (!activeIntervals.empty()) {  // 如果有活动的区间int height = 0;  // 当前扫描线覆盖的总高度int prevY = -1;  // 前一个区间的y坐标// 遍历所有活动区间,计算覆盖的高度for (const auto& interval : activeIntervals) {if (prevY == -1) {  // 如果是第一个区间prevY = interval.first;  // 初始化prevY}if (interval.first > prevY) {  // 如果当前区间与前一个区间不重叠height += interval.first - prevY;  // 累加高度}prevY = std::max(prevY, interval.second);  // 更新prevY}// 计算当前扫描线与前一个扫描线之间的面积,并累加到总面积totalArea += height * (currentX - prevX);}prevX = currentX;  // 更新prevXif (event.isStart) {  // 如果是矩形的开始事件activeIntervals.insert({event.y1, event.y2});  // 将区间加入活动集合} else {  // 如果是矩形的结束事件activeIntervals.erase(activeIntervals.find({event.y1, event.y2}));  // 将区间从活动集合中移除}}return totalArea;  // 返回总面积
}

三、总结

  • 线段树:适用于区间查询和更新操作,常用于处理动态区间问题。

  • 扫描线:适用于处理几何问题,特别是与平面中的矩形、线段等相关的问题。

        这两种算法思想在解决特定类型的问题时非常有效,理解它们的原理和应用场景有助于在编程竞赛和实际开发中更好地解决问题。

http://www.dtcms.com/wzjs/599083.html

相关文章:

  • 深圳网页网站设计网站如何带来流量
  • 做网站运营有前景么网站开发专业定制
  • 网站接口设置羊绒制品有限公司网站建设论文
  • 住房和成乡建设部网站课堂资源管理网站开发需求分析
  • 广西建设职业技术学院教育网站百度自己网站排名
  • 茶叶网站开发目的和意义全网整合营销
  • 自己做网站赚佣金纹绣培训班一般价格多少
  • wordpress还原网站源码wordpress主菜单下拉箭头怎么设置
  • 网站提示503百度百科网站开发
  • 企业建站平台哪个好wordpress 获取所有页面
  • 做网站的素材都在哪里下载兰州网站建设招聘最新
  • 如何建设网站兴田德润可以吗服装网站建设优点和缺点
  • 网站建设专用术语网站优化建设广州
  • 南宁网站seo外包农林牧渔行业网站建设
  • 网站建设用什么书中国制造网外贸平台多少钱
  • 做静态网站有什么建议国内永久免费crm系统破解版
  • 建筑公司企业信用分在哪里查昆明网站排名优化费用
  • 网站建设时间查询云南人
  • wordpress 价格表插件丁的老头seo博客
  • 昆明网站搭建公司张家界建设网站
  • 网站开发设计jw100金融企业如何做好网络推广
  • 大连网站设计费用乐清在线网
  • 网站建设 万网重庆网站建设开发
  • html如何建网站绿色农业网站源码
  • 网站建设广告语临沂在线上网站建设
  • 一起做网店广州站互联网舆情监控系统
  • 二手房公司如何做网站wordpress 官网
  • 做漆包线的招聘网站义乌市网站建设代理
  • 网站备案号码查询广州市越秀区建设局网站
  • 神华两学一做网站网站建设怎么做账务处理