Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <iostream>
- #include <vector>
- using namespace std;
- enum RequestCode {rangeSum, rangeMin, rangeMax};
- vector <int> segment_tree;
- int data[] = {21, 2, 7, 3, 4, 5, 1, 6, 9, 32, 11, 13, 23, 17, 8};
- size_t arrLength = sizeof data / sizeof(data[0]);
- void initSegmentTree() {
- int length = 2 * pow(2.0, floor(log((double) arrLength ) / log(2.0)) + 1 );
- segment_tree.clear();
- segment_tree.resize(length, 0);
- }
- void buildHelper( RequestCode code, int node, int begin, int end ) {
- if (begin == end) {
- if (code == rangeSum) segment_tree[node] = data[begin];
- else segment_tree[node] = begin;
- return;
- }
- int leftIndx = 2 * node, rightIndx = 2 * node + 1;
- buildHelper(code, leftIndx, begin, (begin + end) / 2);
- buildHelper(code, rightIndx, (begin + end) / 2 + 1, end);
- int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx];
- if(code == rangeSum) segment_tree[node] = lContent + rContent;
- if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent;
- if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent;
- }
- void buildSegmentTree(RequestCode code) {
- buildHelper(code, 1, 0, arrLength - 1);
- }
- int queryHelper(RequestCode code, int node, int begin, int end, int i, int j) {
- if (i > end || j < begin) return -1;
- if (begin >= i && end <= j) return segment_tree[node];
- int pos1 = queryHelper(code, 2 * node, begin, (begin + end) / 2, i, j);
- int pos2 = queryHelper(code, 2 * node + 1, (begin + end) / 2 + 1, end, i, j);
- if(pos1 == -1) return pos2;
- if(pos2 == -1) return pos1;
- if (code == rangeSum) {
- return pos1 + pos2;
- } else if(code == rangeMin) {
- return (data[pos1] <= data[pos2]) ? pos1 : pos2;
- } else return (data[pos1] >= data[pos2]) ? pos1 : pos2;
- }
- int query(RequestCode code, int lower, int upper) {
- return queryHelper(code, 1, 0, arrLength - 1, lower, upper);
- }
- /* root to leaf */
- void updateHelper(RequestCode code, int node, int begin, int end, int index, int value ) {
- // this is the only condition and change that makes this updateHelper() function different from buildHelper()
- if( index < begin || index > end || begin > end ) return;
- if( begin == end ) {
- data[begin] = value; // data array is needed to be updated
- // rest of the code is same as buildHelper() method :D
- if(code == rangeSum) segment_tree[node] = data[begin];
- else segment_tree[node] = begin;
- return;
- }
- int leftIndx = node * 2, rightIndx = node * 2 + 1;
- updateHelper(code, leftIndx, begin, ( begin + end ) / 2, index, value );
- updateHelper(code, rightIndx, ( begin + end ) / 2 + 1, end, index, value );
- int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx];
- if(code == rangeSum) segment_tree[node] = lContent + rContent;
- if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent;
- if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent;
- }
- void update(RequestCode code, int index, int item) {
- updateHelper(code, 1, 0, arrLength - 1, index, item);
- }
- int main() {
- initSegmentTree();
- buildSegmentTree(rangeMin);
- cout << query(rangeMin, 0, 8) << "\n";
- update(rangeMin, 6, 100);
- cout << query(rangeMin, 0, 8) << "\n";
- buildSegmentTree(rangeMax);
- cout << query(rangeMax, 0, 8) << "\n";
- buildSegmentTree(rangeSum);
- cout << query(rangeSum, 0, 8);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement