Advertisement
Kaidul

Segment Tree - Range Minimum Query

Jan 7th, 2013
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.64 KB | None | 0 0
  1. #include <algorithm>
  2. #include <bitset>
  3. #include <cctype>
  4. #include <cmath>
  5. #include <complex>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <cstring>
  9. #include <ctime>
  10. #include <deque>
  11. #include <fstream>
  12. #include <iostream>
  13. #include <list>
  14. #include <climits>
  15. #include <map>
  16. #include <memory>
  17. #include <queue>
  18. #include <set>
  19. #include <sstream>
  20. #include <stack>
  21. #include <string>
  22. #include <utility>
  23. #include <vector>
  24. #include <iomanip>
  25.  
  26. using namespace std;
  27.  
  28. #define REP(i,n) for(__typeof(n) i=0; i<(n); i++)
  29. #define FOR(i,a,b) for(__typeof(b) i=(a); i<=(b); i++)
  30. #define RFOR(i,a,b) for(__typeof(b) i=(a); i>(b); i--)
  31. #define RESET(t,value) memset((t), value, sizeof(t))
  32.  
  33. #define READ(f) freopen(f, "r", stdin)
  34. #define WRITE(f) freopen(f, "w", stdout)
  35.  
  36. #define PI acos(-1.0)
  37. #define INF (1<<30)
  38. #define eps 1e-8
  39. #define pb push_back
  40. #define ppb pop_back
  41. #define pii pair<int, int>
  42. #define G struct Graph
  43.  
  44. typedef long long int64;
  45. typedef unsigned long long ui64;
  46. typedef long double d64;
  47.  
  48. template< class T > T gcd(T a, T b) {
  49.     return (b != 0 ? gcd<T>(b, a%b) : a);
  50. }
  51. template< class T > T lcm(T a, T b) {
  52.     return (a / gcd<T>(a, b) * b);
  53. }
  54. template< class T > void setmax(T &a, T b) {
  55.     if(a < b) a = b;
  56. }
  57. template< class T > void setmin(T &a, T b) {
  58.     if(b < a) a = b;
  59. }
  60.  
  61. vector < int > pset (1000);
  62. void initSet(int _size) {
  63.     pset.resize(_size);
  64.     FOR(i,0,_size-1) pset[i] = i;
  65. }
  66. int findSet(int i) {
  67.     return (pset[i]== i)? i : (pset[i] = findSet(pset[i]));
  68. }
  69. void unionSet(int i,int j) {
  70.     pset[findSet(i)]=findSet(j);
  71. }
  72. bool isSameSet(int i,int j) {
  73.     return findSet(i)==findSet(j);
  74. }
  75.  
  76. #define Max 100
  77. /**
  78.  *@code starts
  79. **/
  80.  
  81. /*
  82. Segment Tree Library
  83. The segment tree is stored like a heap array
  84. */
  85.  
  86. #define RANGE_SUM 0
  87. #define RANGE_MIN 1
  88. #define RANGE_MAX 2
  89.  
  90. vector <int> segment_tree;
  91.  
  92. void init_segment_tree(int N) { // if original array size is N
  93.  
  94.     // the required segment tree array length is 2*2^(floor(log2(N))) + 1;
  95.     int length = (2 * pow(2.0, floor(log((double)N) / log(2.0)) + 1 ) );
  96.     // resize the vector and fill with zero
  97.     segment_tree.resize(length, 0);
  98. }
  99.  
  100. void build_segment_tree( int code, int A[], int node, int begin, int end ) {
  101.     if (begin == end) {
  102.         if (code == RANGE_SUM) {
  103.             //store value of the cell
  104.             segment_tree[node] = A[begin];
  105.         } else {
  106.             //if RANGE_MIN/MAX store index
  107.             segment_tree[node] = begin;
  108.         }
  109.     } else {
  110.         //recursively compute the values in the left and right subtrees
  111.         int leftIndx = 2 * node, rightIndx = 2 * node + 1;
  112.         build_segment_tree(code, A, leftIndx, begin, (begin + end) / 2);
  113.         build_segment_tree(code, A, rightIndx, (begin + end) / 2 + 1, end);
  114.         int lContent = segment_tree[leftIndx], rContent = segment_tree[rightIndx];
  115.  
  116.         if (code == RANGE_SUM) { // make this segment contains sum of left and right subtree
  117.             segment_tree[node] = lContent + rContent;
  118.         } else { // code == RANGE_MIN/MAX
  119.             int lValue = A[lContent], rValue = A[rContent];
  120.             if (code == RANGE_MIN) {
  121.                 segment_tree[node] = (lValue <= rValue) ? lContent : rContent;
  122.             } else {
  123.                 segment_tree[node] = (lValue >= rValue) ? lContent : rContent;
  124.             }
  125.  
  126.         }
  127.  
  128.     }
  129.  
  130. }
  131.  
  132. //[r1,r2] = [r1, (r1+r2)/2] , [(r1+r2)/2 + 1, r2]
  133.  
  134. int query(int code, int A[], int node, int begin, int end, int i, int j) {
  135.     // i = left index, j = right index
  136.     if (i > end || j < begin) {
  137.         // if the current interval does not intersect query interval
  138.         return -1;
  139.     }
  140.  
  141.     if (begin >= i && end <= j) {
  142.         // if the current interval is inside query interval
  143.         return segment_tree[node];
  144.     }
  145.  
  146.     // compute the minimum position in the left and right part of the interval
  147.     int pos1 = query(code, A, 2 * node, begin, (begin + end) / 2, i, j);
  148.     int pos2 = query(code, A, 2 * node + 1, (begin + end) / 2 + 1, end, i, j);
  149.  
  150.     // return the position where the overall minimum is
  151.     if(pos1 == -1) return pos2; // can happen if we try to access segment outside query
  152.     if(pos2 == -1) return pos1; // same as above
  153.  
  154.     if (code == RANGE_SUM) {
  155.         return pos1 + pos2;
  156.     } else if(code == RANGE_MIN) {
  157.         return (A[pos1] <= A[pos2]) ? pos1 : pos2;
  158.     } else return (A[pos1] >= A[pos2]) ? pos1 : pos2;
  159. }
  160.  
  161. int main() {
  162.     int A[] = {8, 7, 3, 9, 5, 1, 10};
  163.     init_segment_tree(7);
  164.     build_segment_tree(RANGE_MIN, A, 1, 0, 6);
  165.     cout << "RMQ(1, 3) : " << query(RANGE_MIN, A, 1, 0, 6, 1, 3);
  166.     return EXIT_SUCCESS;
  167. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement