Segment Tree - Sum of given range

简单点说其实Segment Tree就是二分法的灵活运用。

需要的基础知识:

1 二分法

2 二叉树

3 最好熟悉堆排序

操作就是二分法和堆排序巧妙地合并起来。

有了这些基础知识Segment Tree就没有任何难度了。

参考原文:

http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/

下面程序是一个类,现在只实现查找sum的操作。

注意:

1 如何在数组中定义树的跟和孩子节点,及如何计算 --  堆排序也需要的知识: leftchild = root * 2 + 1; rightchild = root * 2 + 2

2 如何定义树高度和树的最大节点数 -- 利用满叉树的特性: maxSize = pow(2, height) - 1

3 数组的区间和查找的区间和树的节点位置是分开计算的,并且需要仔细对好

4 如果不熟悉二分法,请先学习二分法

#include <stdio.h>
#include <cmath>

class SumofGivenRangeSegmentTree_2
{
	int *segTree;
	int tSize;

	int sumHelper(int Tlow, int Tup, int Qlow, int Qup, int root)
	{
		if (Qlow <= Tlow && Tup <= Qup) return segTree[root];
		if (Tup < Qlow || Qup < Tlow) return 0;

		int Tmid = Tlow + ((Tup-Tlow)>>1);
		return sumHelper(Tlow, Tmid, Qlow, Qup, (root<<1)+1)
			+ sumHelper(Tmid+1, Tup, Qlow, Qup, (root<<1)+2);
	}

	int getSum(int low, int up)
	{
		if (low < 0 || up >= tSize || low > up)
		{
			puts("Invalid Indices Input");
			return -1;
		}
		return sumHelper(0, tSize-1, low, up, 0);
	}

	int conHelper(int arr[], int low, int up, int root)
	{
		if (low == up)
		{
			segTree[root] = arr[low];
			return arr[low];
		}
		int mid = low + ((up-low)>>1);
		segTree[root] = conHelper(arr, low, mid, (root<<1)+1)
			+ conHelper(arr, mid+1, up, (root<<1)+2);//注意:child下标计算
		return segTree[root];
	}

	void conTree(int arr[])
	{
		int x = (int) ceil(log(tSize)/log(2));//Height of Tree
		int mSize = 2 * (int) pow(2, x) - 1;//Complete Binary Tree‘s Porperty
		segTree = new int[mSize];
		conHelper(arr, 0, tSize-1, 0);
	}

public:
	SumofGivenRangeSegmentTree_2()
	{
		int arr[] = {1, 3, 5, 7, 9, 11};
		tSize = sizeof(arr) / sizeof(arr[0]);
		conTree(arr);
		printf("Sum of values in given range = %d\n", getSum(1, 3));
	}
};

Segment Tree - Sum of given range

时间: 2024-11-10 08:20:18

Segment Tree - Sum of given range的相关文章

2-D range sum query implementation(2-D segment tree)

Google interview question:一个二维数组,有两个方法,一个是update(x,y),更新一个cell的值,一个是query(x1,y1,x2,y2),查询(x1,y1,x2,y2)矩形内所有元素的和. Senario 1. update调用次数远大于query. Senario 2. query调用次数远大于update. Senario 3. 两种方法调用一样多. 对于senario 1,只需要用一个二维数组储存数据,update相应的cell,时间复杂度O(1),qu

SPOJ 11840. Sum of Squares with Segment Tree (线段树,区间更新)

http://www.spoj.com/problems/SEGSQRSS/ SPOJ Problem Set (classical) 11840. Sum of Squares with Segment Tree Problem code: SEGSQRSS Segment trees are extremely useful.  In particular "Lazy Propagation" (i.e. see here, for example) allows one to c

线段树(Segment Tree)(转)

原文链接:线段树(Segment Tree) 1.概述 线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即“子数组”),因而常用于解决数列维护问题,基本能保证每个操作的复杂度为O(lgN). 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即

Lintcode202 Segment Tree Query solution 题解

[题目描述] For an integer array (index from 0 to n-1, where n is the size of this array), in the corresponding Segment Tree, each node stores an extra attribute max to denote the maximum number in the interval of the array (index from start to end). 对于一个

Segment Tree / Binary Indexed Tree

参见 307. Range Sum Query - Mutable Segment Tree Tree Implementation (SegmentTreeNode) https://www.youtube.com/watch?v=rYBtViWXYeI&list=PLLuMmzMTgVK7ug02DDoQsf50OtwVDL1xd&index=1https://leetcode.com/problems/range-sum-query-mutable/discuss/75711/C++

Aizu 2450 Do use segment tree 树链剖分+线段树

Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show.php?pid=39566 Description Given a tree with n (1 ≤ n ≤ 200,000) nodes and a list of q (1 ≤ q ≤ 100,000) queries, process the queries in order and out

线段树(segment tree)

1.概述 线段树,也叫区间树,是一个完全二叉树,它在各个节点保存一条线段(即"子数组"),因而常用于解决数列维护问题,基本能保证每个操作的复杂度为O(lgN). 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以

poj 2985 The k-th Largest Group 求第K大数 Treap, Binary Index Tree, Segment Tree

题目链接:点击打开链接 题意:有两种操作,合并集合,查询第K大集合的元素个数.(总操作次数为2*10^5) 解法: 1.Treap 2.树状数组 |-二分找第K大数 |-二进制思想,逼近第K大数 3.线段树 4.... Treap模板(静态数组) #include <math.h> #include <time.h> #include <stdio.h> #include <limits.h> #include <stdlib.h> const

hdu 5086 Revenge of Segment Tree(BestCoder Round #16)

Revenge of Segment Tree                                                          Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 420    Accepted Submission(s): 180 Problem Description In comput