BotByte

Histogram (segment tree).cpp

Sep 14th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.05 KB | None | 0 0
  1. /*     Largest Area in a histogram using segment tree
  2.     1. Build a RMQ segment tree
  3.     2. Query will provide minimum index
  4.     3. Now for a interval (b, e), we have three options -
  5.        (i) take the whole interval
  6.        (ii) take the left interval from the minIndex
  7.        (iii) take the right interval from the minIndex
  8.     4. Take the maximum value using divide and conquer
  9.     Sample solution : LightOJ - 1083 (Histogram)
  10. */
  11.  
  12. #include <bits/stdc++.h>
  13.  
  14. using namespace std;
  15.  
  16. #define MAX 30008
  17. int arr[MAX], n;
  18.  
  19. struct data {
  20.     int Min, MinIdx;
  21. } tree[4*MAX];
  22.  
  23. void init(int node, int b, int e)
  24. {
  25.     if(b == e){
  26.         tree[node].Min = arr[b];
  27.         tree[node].MinIdx = b;
  28.         return;
  29.     }
  30.     int left = 2*node;
  31.     int right = 2*node + 1;
  32.     int mid = (b+e)/2;
  33.     init(left, b, mid);
  34.     init(right, mid+1, e);
  35.     if(tree[left].Min <= tree[right].Min){
  36.         tree[node].Min = tree[left].Min;
  37.         tree[node].MinIdx = tree[left].MinIdx;
  38.     }
  39.     else {
  40.         tree[node].Min = tree[right].Min;
  41.         tree[node].MinIdx = tree[right].MinIdx;
  42.     }
  43. }
  44.  
  45. int query(int node, int b, int e, int i, int j)
  46. {
  47.     if(i > e || j < b) return -1;
  48.     if(b >= i && e <= j) return tree[node].MinIdx;
  49.     int left = 2*node;
  50.     int right = 2*node + 1;
  51.     int mid = (b+e)/2;
  52.     int p = query(left, b, mid, i, j);
  53.     int q = query(right, mid+1, e, i, j);
  54.     if(p == -1) return q;
  55.     if(q == -1) return p;
  56.     if(arr[p] <= arr[q]) return p;
  57.     else return q;
  58. }
  59.  
  60. int area(int b, int e)
  61. {
  62.     if(b == e) return arr[b];
  63.     if(b > e) return 0;
  64.     int idx = query(1, 1, n, b, e);
  65.     int res = max(area(b, idx-1), area(idx+1, e));
  66.     int calc = (e-b+1) * arr[idx];
  67.     res = max(res, calc);
  68.     return res;
  69. }
  70.  
  71. int main()
  72. {
  73.     //freopen("in.txt", "r", stdin);
  74.     int cases;
  75.     scanf("%d", &cases);
  76.     int caseno = 0;
  77.     while(cases--){
  78.         scanf("%d", &n);
  79.         for(int i=1; i<=n; i++) scanf("%d", &arr[i]);
  80.         init(1, 1, n);
  81.         printf("Case %d: %d\n", ++caseno, area(1, n));
  82.     }
  83. }
Advertisement
Add Comment
Please, Sign In to add comment