Advertisement
Iloominatry

[Lazy Segment Tree] Dima & Staircase

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