Guest User

Untitled

a guest
Sep 29th, 2016
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  1. /**
  2. * In this code we have a very large array called arr, and very large set of operations
  3. * Operation #1: Increment the elements within range [i, j] with value val
  4. * Operation #2: Get max element within range [i, j]
  5. * Build tree: build_tree(1, 0, N-1)
  6. * Update tree: update_tree(1, 0, N-1, i, j, value)
  7. * Query tree: query_tree(1, 0, N-1, i, j)
  8. * Actual space required by the tree = 2*2^ceil(log_2(n)) - 1
  9. */
  10.  
  11. #include<iostream>
  12. #include<algorithm>
  13. using namespace std;
  14.  
  15. #include<string.h>
  16. #include<math.h>
  17.  
  18. #define N 20
  19. #define MAX (1+(1<<6)) // Why? :D
  20. #define inf 0x7fffffff
  21.  
  22. int arr[N];
  23. int tree[MAX];
  24. int lazy[MAX];
  25.  
  26. /**
  27. * Build and init tree
  28. */
  29. void build_tree(int node, int a, int b) {
  30. if(a > b) return; // Out of range
  31.  
  32. if(a == b) { // Leaf node
  33. tree[node] = arr[a]; // Init value
  34. return;
  35. }
  36.  
  37. build_tree(node*2, a, (a+b)/2); // Init left child
  38. build_tree(node*2+1, 1+(a+b)/2, b); // Init right child
  39.  
  40. tree[node] = max(tree[node*2], tree[node*2+1]); // Init root value
  41. }
  42.  
  43. /**
  44. * Increment elements within range [i, j] with value value
  45. */
  46. void update_tree(int node, int a, int b, int i, int j, int value) {
  47.  
  48. if(lazy[node] != 0) { // This node needs to be updated
  49. tree[node] += lazy[node]; // Update it
  50.  
  51. if(a != b) {
  52. lazy[node*2] += lazy[node]; // Mark child as lazy
  53. lazy[node*2+1] += lazy[node]; // Mark child as lazy
  54. }
  55.  
  56. lazy[node] = 0; // Reset it
  57. }
  58.  
  59. if(a > b || a > j || b < i) // Current segment is not within range [i, j]
  60. return;
  61.  
  62. if(a >= i && b <= j) { // Segment is fully within range
  63. tree[node] += value;
  64.  
  65. if(a != b) { // Not leaf node
  66. lazy[node*2] += value;
  67. lazy[node*2+1] += value;
  68. }
  69.  
  70. return;
  71. }
  72.  
  73. update_tree(node*2, a, (a+b)/2, i, j, value); // Updating left child
  74. update_tree(1+node*2, 1+(a+b)/2, b, i, j, value); // Updating right child
  75.  
  76. tree[node] = max(tree[node*2], tree[node*2+1]); // Updating root with max value
  77. }
  78.  
  79. /**
  80. * Query tree to get max element value within range [i, j]
  81. */
  82. int query_tree(int node, int a, int b, int i, int j) {
  83.  
  84. if(a > b || a > j || b < i) return -inf; // Out of range
  85.  
  86. if(lazy[node] != 0) { // This node needs to be updated
  87. tree[node] += lazy[node]; // Update it
  88.  
  89. if(a != b) {
  90. lazy[node*2] += lazy[node]; // Mark child as lazy
  91. lazy[node*2+1] += lazy[node]; // Mark child as lazy
  92. }
  93.  
  94. lazy[node] = 0; // Reset it
  95. }
  96.  
  97. if(a >= i && b <= j) // Current segment is totally within range [i, j]
  98. return tree[node];
  99.  
  100. int q1 = query_tree(node*2, a, (a+b)/2, i, j); // Query left child
  101. int q2 = query_tree(1+node*2, 1+(a+b)/2, b, i, j); // Query right child
  102.  
  103. int res = max(q1, q2); // Return final result
  104.  
  105. return res;
  106. }
  107.  
  108. int main() {
  109. for(int i = 0; i < N; i++) arr[i] = 1;
  110.  
  111. build_tree(1, 0, N-1);
  112.  
  113. memset(lazy, 0, sizeof lazy);
  114.  
  115. update_tree(1, 0, N-1, 0, 6, 5); // Increment range [0, 6] by 5. here 0, N-1 represent the current range.
  116. update_tree(1, 0, N-1, 7, 10, 12); // Incremenet range [7, 10] by 12. here 0, N-1 represent the current range.
  117. update_tree(1, 0, N-1, 10, N-1, 100); // Increment range [10, N-1] by 100. here 0, N-1 represent the current range.
  118.  
  119. cout << query_tree(1, 0, N-1, 0, N-1) << endl; // Get max element in range [0, N-1]
  120. }
Add Comment
Please, Sign In to add comment