Last active
July 11, 2019 07:27
-
-
Save Se7soz/4369150 to your computer and use it in GitHub Desktop.
An example of segment tree implementation, to read the whole topic please visit http://se7so.blogspot.com
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* In this code we have a very large array called arr, and very large set of operations | |
* Operation #1: Increment the elements within range [i, j] with value val | |
* Operation #2: Get max element within range [i, j] | |
* Build tree: build_tree(1, 0, N-1) | |
* Update tree: update_tree(1, 0, N-1, i, j, value) | |
* Query tree: query_tree(1, 0, N-1, i, j) | |
*/ | |
#include<iostream> | |
#include<algorithm> | |
using namespace std; | |
#include<string.h> | |
#include<math.h> | |
#define N 20 | |
#define MAX (1+(1<<6)) // Why? :D | |
#define inf 0x7fffffff | |
int arr[N]; | |
int tree[MAX]; | |
/** | |
* Build and init tree | |
*/ | |
void build_tree(int node, int a, int b) { | |
if(a > b) return; // Out of range | |
if(a == b) { // Leaf node | |
tree[node] = arr[a]; // Init value | |
return; | |
} | |
build_tree(node*2, a, (a+b)/2); // Init left child | |
build_tree(node*2+1, 1+(a+b)/2, b); // Init right child | |
tree[node] = max(tree[node*2], tree[node*2+1]); // Init root value | |
} | |
/** | |
* Increment elements within range [i, j] with value value | |
*/ | |
void update_tree(int node, int a, int b, int i, int j, int value) { | |
if(a > b || a > j || b < i) // Current segment is not within range [i, j] | |
return; | |
if(a == b) { // Leaf node | |
tree[node] += value; | |
return; | |
} | |
update_tree(node*2, a, (a+b)/2, i, j, value); // Updating left child | |
update_tree(1+node*2, 1+(a+b)/2, b, i, j, value); // Updating right child | |
tree[node] = max(tree[node*2], tree[node*2+1]); // Updating root with max value | |
} | |
/** | |
* Query tree to get max element value within range [i, j] | |
*/ | |
int query_tree(int node, int a, int b, int i, int j) { | |
if(a > b || a > j || b < i) return -inf; // Out of range | |
if(a >= i && b <= j) // Current segment is totally within range [i, j] | |
return tree[node]; | |
int q1 = query_tree(node*2, a, (a+b)/2, i, j); // Query left child | |
int q2 = query_tree(1+node*2, 1+(a+b)/2, b, i, j); // Query right child | |
int res = max(q1, q2); // Return final result | |
return res; | |
} | |
int main() { | |
for(int i = 0; i < N; i++) arr[i] = 1; | |
build_tree(1, 0, N-1); | |
update_tree(1, 0, N-1, 0, 6, 5); // Increment range [0, 6] by 5 | |
update_tree(1, 0, N-1, 7, 10, 12); // Incremenet range [7, 10] by 12 | |
update_tree(1, 0, N-1, 10, N-1, 100); // Increment range [10, N-1] by 100 | |
cout << query_tree(1, 0, N-1, 0, N-1) << endl; // Get max element in range [0, N-1] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment