#include <bits/stdc++.h> // Standard headers (iostream, vector, stack, algorithm for max)
using namespace std; // Standard namespace
// Finds the index of the next smaller element to the right for each element
// Uses a monotonic stack
vector<int> nextSmallerElement(vector<int> arr) {
vector<int> solution(arr.size()); // Result array for next smaller element indices
stack<int> st; // Stack to store indices
st.push(-1); // Sentinel value: -1 indicates no smaller element to the right
// Iterate from right to left
for(int i = arr.size() - 1; i >= 0; i--) {
int curr = arr[i]; // Current element's value
// Pop elements from stack whose values are >= current element's value
// Maintain increasing order of values (based on indices) in the stack from bottom to top
while(st.top() != -1 && arr[st.top()] >= curr) {
solution[i] = st.top(); // The element at stack's top is the next smaller element's index
st.push(i); // Push current element's index onto stack
// Finds the index of the previous smaller element to the left for each element
// Uses a monotonic stack
vector<int> previousSmallerElement(vector<int> arr) {
vector<int> solution(arr.size()); // Result array for previous smaller element indices
stack<int> st; // Stack to store indices
st.push(-1); // Sentinel value: -1 indicates no smaller element to the left
// Iterate from left to right
for(int i = 0; i < arr.size(); i++) {
int curr = arr[i]; // Current element's value
// Pop elements from stack whose values are >= current element's value
// Maintain increasing order of values (based on indices) in the stack from bottom to top
while(st.top() != -1 && arr[st.top()] >= curr) {
solution[i] = st.top(); // The element at stack's top is the previous smaller element's index
st.push(i); // Push current element's index onto stack
// Calculates the largest rectangular area in a histogram
int largestRectangularArea(vector<int> height) {
int maxArea = 0; // Initialize maximum area
// Step 1: Find next smaller element for each bar
vector<int> next = nextSmallerElement(height);
// Step 2: Find previous smaller element for each bar
vector<int> prev = previousSmallerElement(height);
// Step 3: Calculate area for each bar as a potential height
for(int i = 0; i < n; i++) {
// If no smaller element to the right, extend to the end of the histogram
next[i] = n; // Set index to 'n' (one past last valid index)
int length = height[i]; // Height of the current bar
// Width is (index of next smaller) - (index of previous smaller) - 1
// This gives the count of bars *between* them, plus the current bar itself
int breadth = next[i] - prev[i] - 1;
int newArea = length * breadth; // Calculate area for this bar
maxArea = max(newArea, maxArea); // Update maxArea if current area is larger
return maxArea; // Return the maximum area found
vector<int> height = {2, 1, 5, 6, 2, 3}; // Example histogram heights
// Calculate and print the largest rectangular area
cout << "Required area : " << largestRectangularArea(height) << endl;
// Expected output for {2, 1, 5, 6, 2, 3}:
// next: [1, -1, 5, 5, -1, -1] -> transformed next: [1, 6, 5, 5, 6, 6]
// prev: [-1, -1, 1, 2, 1, 4]
// i=0, h=2: n=1, p=-1, b=1-(-1)-1=1, A=2*1=2
// i=1, h=1: n=6, p=-1, b=6-(-1)-1=6, A=1*6=6
// i=2, h=5: n=5, p=1, b=5-1-1=3, A=5*3=15
// i=3, h=6: n=5, p=2, b=5-2-1=2, A=6*2=12
// i=4, h=2: n=6, p=1, b=6-1-1=4, A=2*4=8
// i=5, h=3: n=6, p=4, b=6-4-1=1, A=3*1=3