Advertisement
Guest User

Untitled

a guest
Feb 20th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.84 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. #include <sstream>
  5. #include <cstdio>
  6. #include <set>
  7. #include <algorithm>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <map>
  11. #include <stack>
  12. #include <queue>
  13. #include <vector>
  14. #include <stdio.h>
  15. #include <math.h>
  16.  
  17. using namespace std;
  18.  
  19. #define _CRT_SECURE_NO_DEPRECATE
  20. typedef vector<int> vi;
  21.  
  22. #define REP(i, a, b) for (int i = int(a); i < int(b); i++)
  23. #define REPV(i, a, b) for (int i = int(a); i >= int(b); i--)
  24. #define YES 2
  25. #define NO 1
  26.  
  27. // Segment Tree Library
  28. // The segment tree is stored like a heap array
  29. #define RANGE_SUM 0
  30. #define RANGE_MIN 1
  31. #define RANGE_MAX 2
  32. vi segment_tree;
  33.  
  34. void init_segment_tree(int N) { // if original array size is N,
  35. // the required segment_tree array length is 2*2^(floor(log2(N)) + 1);
  36.     int length = (int) (2 * pow(2.0, floor(log2((double) N) + 1)));
  37.     segment_tree.resize(length, 0); // resize this vector and fill with 0
  38. }
  39.  
  40. void build_segment_tree(int code, int A[], int node, int b, int e) {
  41.     if (b == e) { // as b == e, either one is fine
  42.         if (code == RANGE_SUM)
  43.             segment_tree[node] = A[b]; // store value of this cell
  44.         else
  45.             segment_tree[node] = b; // if RANGE_MIN/MAXIMUM, store index
  46.     } else { // recursively compute the values in the left and right subtrees
  47.         int leftIdx = 2 * node, rightIdx = 2 * node + 1;
  48.         build_segment_tree(code, A, leftIdx, b, (b + e) / 2);
  49.         build_segment_tree(code, A, rightIdx, (b + e) / 2 + 1, e);
  50.         int lContent = segment_tree[leftIdx], rContent = segment_tree[rightIdx];
  51.         if (code == RANGE_SUM) // make this segment contains sum of left and right subtree
  52.             segment_tree[node] = lContent + rContent;
  53.         else { // (code == RANGE_MIN/MAXIMUM)
  54.             int lValue = A[lContent], rValue = A[rContent];
  55.             if (code == RANGE_MIN)
  56.                 segment_tree[node] = (lValue <= rValue) ? lContent : rContent;
  57.             else
  58.                 segment_tree[node] = (lValue >= rValue) ? lContent : rContent;
  59.         }
  60.     }
  61. }
  62.  
  63. int query(int code, int A[], int node, int b, int e, int i, int j) {
  64.     if (i > e || j < b)
  65.         return -1; // if the current interval does not intersect query interval
  66.     if (b >= i && e <= j)
  67.         return segment_tree[node]; // if the current interval is inside query interval
  68. // compute the minimum position in the left and right part of the interval
  69.     int p1 = query(code, A, 2 * node, b, (b + e) / 2, i, j);
  70.     int p2 = query(code, A, 2 * node + 1, (b + e) / 2 + 1, e, i, j);
  71. // return the position where the overall minimum is
  72.     if (p1 == -1)
  73.         return p2; // can happen if we try to access segment outside query
  74.     if (p2 == -1)
  75.         return p1; // same as above
  76.     if (code == RANGE_SUM)
  77.         return p1 + p2;
  78.     else if (code == RANGE_MIN)
  79.         return (A[p1] <= A[p2]) ? p1 : p2;
  80.     else
  81.         return (A[p1] >= A[p2]) ? p1 : p2;
  82. }
  83.  
  84. void update(int code, int A[], int node, int b, int e, int index, int val) {
  85.     if (index > e || index < b)
  86.         return;
  87.     if (index == e && index == b) {
  88.         A[index] = val;
  89.         if(code == RANGE_SUM)
  90.             segment_tree[node] = val;
  91.         return;
  92.     }
  93.     int leftIdx = 2 * node, rightIdx = 2 * node + 1;
  94.     update(code, A, leftIdx, b, (b + e) / 2, index, val);
  95.     update(code, A, rightIdx, (b + e) / 2 + 1, e, index, val);
  96.     int lContent = segment_tree[leftIdx], rContent = segment_tree[rightIdx];
  97.     if(code == RANGE_SUM)
  98.         segment_tree[node] = lContent + rContent;
  99.     else{
  100.         int lValue = A[lContent], rValue = A[rContent];
  101.         if(code == RANGE_MIN){
  102.             segment_tree[node] = (lValue <= rValue) ? lContent : rContent;
  103.         }else{
  104.             segment_tree[node] = (lValue >= rValue) ? lContent : rContent;
  105.         }
  106.     }
  107. }
  108.  
  109. int main() {
  110.     cout << "Segment Tree " << endl;
  111.     int A[] = { 8, 7, 3, 9, 5, 1, 10 };
  112.     init_segment_tree(7);
  113.     build_segment_tree(RANGE_MIN, A, 1, 0, 6);
  114.     REP(i,0,segment_tree.size())
  115.     {
  116.         cout << segment_tree[i] << " ";
  117.     }
  118.     cout << endl;
  119.     printf("%d\n", query(RANGE_MIN, A, 1, 0, 6, 1, 3)); // answer is index 2
  120.     return 0;
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement