博客
关于我
poj 3264(简单线段树)
阅读量:801 次
发布时间:2023-03-03

本文共 2705 字,大约阅读时间需要 9 分钟。

线段树是解决区间查询问题的高效数据结构,特别适用于动态查询区域内的最大值和最小值。在本文中,我们将使用线段树来处理每个查询请求,找到区间内的最大值与最小值之差。

线段树的构建

线段树的每个节点表示一个区间,该区间内的所有节点都具有相同的性质(在本例中,最大值和最小值)。每个节点包含以下信息:

  • 区间起始点(b)
  • 区间结束点(d)
  • 区间内的最大值(mx)
  • 区间内的最小值(mi)
  • 左孩子节点指针(Tl)
  • 右孩子节点指针(Tr)

线段树的构建采用递归的方法,具体步骤如下:

  • 创建一个节点,初始化为当前区间的左端点和右端点。
  • 如果当前区间的起始点等于结束点,说明该节点是一个叶子节点,直接存储该值。
  • 否则,将区间分为左半部分和右半部分,递归构建左孩子和右孩子节点。
  • 从左孩子和右孩子节点中合并得到当前节点的最大值和最小值。
  • 数据插入

    插入数据时,我们需要将一个新的值插入到线段树中,并更新相关节点的最大值和最小值。具体步骤如下:

  • 检查当前节点的区间是否包含插入值。
  • 如果当前节点的区间包含插入值,比较插入值与当前节点的最大值和最小值,更新相应的值。
  • 如果当前节点的区间不包含插入值,根据插入值的位置决定进入左孩子还是右孩子节点。
  • 递归处理左孩子或右孩子节点,直到找到正确的位置并更新值。
  • 查询操作

    查询操作需要找到区间内的最大值和最小值。具体步骤如下:

  • 检查当前节点的区间是否完全包含查询区间。
  • 如果当前节点的区间完全包含查询区间,返回当前节点的最大值和最小值。
  • 否则,分别查询左孩子和右孩子节点,合并结果得到查询区间内的最大值和最小值。
  • 返回结果。
  • 代码实现

    #include 
    #include
    #include
    using namespace std;#define N 50050#define INF 0x3fffffffstruct node { int b, d; int mx, mi; node* Tl; node* Tr;};int cnt;node* Tbuild(int s, int t) { node* tmp = &edge[cnt++]; tmp->mi = INF; tmp->mx = -1; tmp->Tl = tmp->Tr = NULL; tmp->b = s; tmp->d = t; int mid = (s + t) / 2; if (s != t) { tmp->Tl = Tbuild(s, mid); tmp->Tr = Tbuild(mid + 1, t); } return tmp;}void insert(node* tmp, int s, int k) { if (s > tmp->mx) { tmp->mx = s; } if (s < tmp->mi) { tmp->mi = s; } if (tmp->b == tmp->d && tmp->d == k) { return; } int mid = (tmp->b + tmp->d) / 2; if (k <= mid) { insert(tmp->Tl, s, k); } else { insert(tmp->Tr, s, k); }}int findmx(node* tmp, int s, int t) { if (tmp->b == s && tmp->d == t) { return tmp->mx; } int mid = (tmp->b + tmp->d) / 2; if (s > mid) { return findmx(tmp->Tr, max(mid + 1, s), t); } if (t <= mid) { return findmx(tmp->Tl, s, min(mid, t)); } return max(findmx(tmp->Tl, s, mid), findmx(tmp->Tr, mid + 1, t));}int findmi(node* tmp, int s, int t) { if (tmp->b == s && tmp->d == t) { return tmp->mi; } int mid = (tmp->b + tmp->d) / 2; if (s > mid) { return findmi(tmp->Tr, max(mid + 1, s), t); } if (t <= mid) { return findmi(tmp->Tl, s, min(mid, t)); } return min(findmi(tmp->Tl, s, mid), findmi(tmp->Tr, mid + 1, t));}int main() { cnt = 0; scanf("%d%d", &n, &q); head = Tbuild(1, n); for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); insert(head, x, i); } for (int i = 0; i < q; i++) { int A, B; scanf("%d%d", &A, &B); int max_val = findmx(head, A, B); int min_val = findmi(head, A, B); cout << (max_val - min_val) << endl; }}

    总结

    这个代码实现了一个线段树,用于高效处理区间查询问题。通过线段树,我们能够在O(log N)的时间复杂度内找到任意区间内的最大值和最小值,从而快速响应每个查询请求。这种方法特别适用于大规模数据和大量查询的情况,能够显著提高处理效率。

    转载地址:http://ifxfk.baihongyu.com/

    你可能感兴趣的文章
    QGIS中怎样设置图层样式并导出地图样式
    查看>>
    PowerDesigner使用笔记
    查看>>
    QGIS中怎样实现数据坐标系转换
    查看>>
    PowerDesigner学习--基本步骤
    查看>>
    PowerDesigner导出Report通用报表
    查看>>
    PowerDesigner教程系列(二)概念数据模型
    查看>>
    Powerdesigner显示表的comment和列的comment的方法
    查看>>
    PowerDesigner最基础的使用方法入门学习
    查看>>
    PowerDesigner版本控制器设置权限
    查看>>
    PowerDesigner生成数据模型并导出报告
    查看>>
    QGIS中导入dwg文件并使用GetWKT插件获取绘制元素WKT字符串以及QuickWKT插件实现WKT显示在图层
    查看>>
    PowerDesigner逆向工程从SqlServer数据库生成PDM(图文教程)
    查看>>
    PowerEdge T630服务器安装机器学习环境(Ubuntu18.04、Nvidia 1080Ti驱动、CUDA及CUDNN安装)
    查看>>
    PowerPC-object与elf中的符号引用
    查看>>
    QFileSystemModel
    查看>>
    Powershell DSC 5.0 - 参数,证书加密账号,以及安装顺序
    查看>>
    PowerShell 批量签入SharePoint Document Library中的文件
    查看>>
    Powershell 自定义对象小技巧
    查看>>
    pytorch从预训练权重加载完全相同的层
    查看>>
    PowerShell~发布你的mvc网站
    查看>>