zoukankan      html  css  js  c++  java
  • 线段树(Segment Tree)

      线段树也是一种可使用表结构实现的概念上的树形结构,这种方式建立过程如二叉堆中计算节点的左孩子与右孩子一样,但线段树一定是一颗完全二叉树,所以空间复杂度为 $ O(2 * n) $,$ n $ 表示数组大小。重点是要读懂线段树表示是什么意思。

      示例:

      释义:

      根节点 5 --- [0,6] 表示在数组 $ {18,17,13,19,15,11,20} $ 区间 [0,6] 内最小值为数组下标5的数。

      其他节点含义同上。。。

      下面是代码实现:

    #include <iostream>
    #define LC(i) ((i) << 1)
    #define RC(i) ((i) << 1 | 1)
    #define M 10010
    #define min(a, b) ((a) < (b) ? (a) : (b))
    struct { int l, r, val; } SegTree[M];
    int num[] = { 18, 17, 19, 13, 15, 11, 20 };
    void build(int l, int r, int k)
    {
    	if (l == r)
    		SegTree[k].val = num[l];
    	else
    	{
    		int m = (l + r) >> 1;
    		build(l, m, LC(k));
    		build(m + 1, r, RC(k));
    		SegTree[k].val = min(SegTree[LC(k)].val, SegTree[RC(k)].val);
    	}
    }
    void update(int l, int r, int k, int pos, int v)
    {
    	if (l > pos || r < pos || r < l)
    		return;
    	if (l == r)
    	{
    		SegTree[k].val = v;
    		return;
    	}
    	int m = (l + r) >> 1;
    	if (pos <= m)
    		update(l, m, LC(k), pos, v);
    	else
    		update(m + 1, r, RC(k), pos, v);
    	SegTree[k].val = min(SegTree[LC(k)].val, SegTree[RC(k)].val);
    }
    int query(int l, int r, int x, int y, int k)
    {
    	if (l > r || l > y || r < x)
    		return M;
    	if (x <= l && r <= y)
    		return SegTree[k].val;
    	int m = (l + r) >> 1;
    	return min(query(l, m, x, y, LC(k)), query(m + 1, r, x, y, RC(k)));
    }
    int main()
    {
    	int len, x, y, k, v;
    
    	len = (sizeof(num) / sizeof(int)) - 1;
    	build(0, len, 1);
    
    	for (int i = 1; i <= 2 * len; i++)
    		std::cout << SegTree[i].val << ' ';
    	std::cout << std::endl;
    
    	std::cout << "查询[x,y]区间的最小值:" << std::endl;
    	std::cin >> x >> y;
    	std::cout << query(0, len, x, y, 1) << std::endl;
    
    	std::cout << "更新下标k位置上的值:" << std::endl;
    	std::cin >> k >> v;
    	update(0, len, 1, k, v);
    
    	for (int i = 1; i <= 2 * len; i++)
    		std::cout << SegTree[i].val << ' ';
    	std::cout << std::endl;
    	return 0;
    }
    

      参考:

        https://github.com/darkchii/cosmos/blob/master/code/data_structures/src/tree/segment_tree/segment_Tree_rmq.adb

        http://www.cnblogs.com/TenosDoIt/p/3453089.html

  • 相关阅读:
    angular基础
    函数&闭包
    springboot + 拦截器 + 注解 实现自定义权限验证
    idea点击RUN启动报错: Broken configuration due to unavailable plugin or invalid configuration dat
    解决“指定的服务已经标记为删除”问题
    Mybatis中的XML中需要用到的转义符号整理
    springboot 2.0+ 自定义拦截器
    idea中lombok的使用
    springboot集成PageHelper,支持springboot2.0以上版本
    IDEA 修改JSP和后端数据后,页面刷新可以实时更新
  • 原文地址:https://www.cnblogs.com/darkchii/p/9402760.html
Copyright © 2011-2022 走看看