Advertisement
Kaidul

Segment Tree

Apr 13th, 2013
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.67 KB | None | 0 0
  1. #include <cmath>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. enum RequestCode {rangeSum, rangeMin, rangeMax};
  8.  
  9. vector <int> segment_tree;
  10.  
  11. int data[] = {21, 2, 7, 3, 4, 5, 1, 6, 9, 32, 11, 13, 23, 17, 8};
  12. size_t arrLength = sizeof data / sizeof(data[0]);
  13.  
  14.  
  15. void initSegmentTree() {
  16.     int length = 2 * pow(2.0, floor(log((double) arrLength ) / log(2.0)) + 1 );
  17.     segment_tree.clear();
  18.     segment_tree.resize(length, 0);
  19. }
  20.  
  21.  
  22. void buildHelper( RequestCode code, int node, int begin, int end ) {
  23.     if (begin == end) {
  24.         if (code == rangeSum) segment_tree[node] = data[begin];
  25.         else segment_tree[node] = begin;
  26.         return;
  27.     }
  28.     int leftIndx = 2 * node, rightIndx = 2 * node + 1;
  29.  
  30.     buildHelper(code, leftIndx, begin, (begin + end) / 2);
  31.     buildHelper(code, rightIndx, (begin + end) / 2 + 1, end);
  32.  
  33.     int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx];
  34.  
  35.     if(code == rangeSum) segment_tree[node] = lContent + rContent;
  36.     if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent;
  37.     if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent;
  38.  
  39. }
  40.  
  41. void buildSegmentTree(RequestCode code) {
  42.     buildHelper(code, 1, 0, arrLength - 1);
  43. }
  44.  
  45. int queryHelper(RequestCode code, int node, int begin, int end, int i, int j) {
  46.     if (i > end || j < begin) return -1;
  47.  
  48.     if (begin >= i && end <= j) return segment_tree[node];
  49.  
  50.     int pos1 = queryHelper(code, 2 * node, begin, (begin + end) / 2, i, j);
  51.     int pos2 = queryHelper(code, 2 * node + 1, (begin + end) / 2 + 1, end, i, j);
  52.  
  53.     if(pos1 == -1) return pos2;
  54.     if(pos2 == -1) return pos1;
  55.  
  56.     if (code == rangeSum) {
  57.         return pos1 + pos2;
  58.     } else if(code == rangeMin) {
  59.         return (data[pos1] <= data[pos2]) ? pos1 : pos2;
  60.     } else return (data[pos1] >= data[pos2]) ? pos1 : pos2;
  61. }
  62.  
  63. int query(RequestCode code, int lower, int upper) {
  64.     return queryHelper(code, 1, 0, arrLength - 1, lower, upper);
  65. }
  66.  
  67. /* root to leaf */
  68. void updateHelper(RequestCode code, int node, int begin, int end, int index, int value ) {
  69.  
  70.     // this is the only condition and change that makes this updateHelper() function different from buildHelper()
  71.     if( index < begin || index > end || begin > end ) return;
  72.  
  73.     if( begin == end ) {
  74.         data[begin] = value; // data array is needed to be updated
  75.  
  76.         // rest of the code is same as buildHelper() method :D
  77.         if(code == rangeSum) segment_tree[node] = data[begin];
  78.         else segment_tree[node] = begin;
  79.         return;
  80.     }
  81.     int leftIndx = node * 2, rightIndx = node * 2 + 1;
  82.  
  83.     updateHelper(code, leftIndx, begin, ( begin + end ) / 2, index, value );
  84.     updateHelper(code, rightIndx, ( begin + end ) / 2 + 1, end, index, value );
  85.  
  86.     int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx];
  87.  
  88.     if(code == rangeSum) segment_tree[node] = lContent + rContent;
  89.     if(code == rangeMin) segment_tree[node] = ( data[lContent] <= data[rContent] ) ? lContent : rContent;
  90.     if(code == rangeMax) segment_tree[node] = ( data[lContent] >= data[rContent] ) ? lContent : rContent;
  91. }
  92.  
  93. void update(RequestCode code, int index, int item) {
  94.     updateHelper(code, 1, 0, arrLength - 1, index, item);
  95. }
  96.  
  97. int main() {
  98.     initSegmentTree();
  99.  
  100.     buildSegmentTree(rangeMin);
  101.     cout << query(rangeMin, 0, 8) << "\n";
  102.  
  103.     update(rangeMin, 6, 100);
  104.     cout << query(rangeMin, 0, 8) << "\n";
  105.  
  106.  
  107.  
  108.     buildSegmentTree(rangeMax);
  109.     cout << query(rangeMax, 0, 8) << "\n";
  110.  
  111.     buildSegmentTree(rangeSum);
  112.     cout << query(rangeSum, 0, 8);
  113.     return 0;
  114. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement