Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Largest Rectangle in a Histogram

A histogram is made of a number of contiguous bars, which have same width.

For a given histogram with $N$ bars which have a width of 1 and a height of $h_i$ = $h_1, h_2, ... , h_N$ respectively, find the area of the largest rectangular area.

Constraints

$1 \leq N \leq 10^5$

$0 \leq h_i \leq 10^9$

Input

The input is given in the following format.

$N$

$h_1$ $h_2$ ... $h_N$

Output

Print the area of the largest rectangle.

Sample Input 1

8
2 1 3 5 3 4 2 1

Sample Output 1

12

Sample Input 2

3
2 0 1

Sample Output 2

2

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
	static void Main()
	{
    int n = int.Parse(Console.ReadLine());
    long[] nums = Array.ConvertAll(Console.ReadLine().Split(' '),long.Parse);
		Console.WriteLine(LargestRectangle(nums));
	}

  static long LargestRectangle(long[] lengths)
  {//x軸に接する底辺1、高さlengthsの長方形を繋げた時、最大長方形の面積をO(n)で返す
    if(lengths.Length == 0) return 0;
    long answer = lengths[0];
    int n = lengths.Length;
    var rectangleStack = new Stack<long[]>();//x座標と高さ
    rectangleStack.Push(new long[2]{0,lengths[0]});
    long[] topMemo = new long[2];
    
    for(int i = 1; i < n; i++)
    {
      if(rectangleStack.Count() > 0) topMemo = rectangleStack.Peek();
      
      if(topMemo[1] < lengths[i]) rectangleStack.Push(new long[2]{i,lengths[i]});
      else if(topMemo[1] > lengths[i])
      {
        long memo = 0;
        while(rectangleStack.Count() > 0)
        {
          if(rectangleStack.Peek()[1] > lengths[i])
          {
            answer = Math.Max(answer, rectangleStack.Peek()[1]*(i-rectangleStack.Peek()[0]));
            memo = rectangleStack.Peek()[0];
            
            if(rectangleStack.Count() == 1)
            {
              rectangleStack.Pop();
              rectangleStack.Push(new long[2]{memo, lengths[i]});
              break;
            }
            else rectangleStack.Pop();
          }else
          {
            rectangleStack.Push(new long[2]{memo, lengths[i]});
            break;
          }
        }
      }

      if(i == n-1 && rectangleStack.Count() > 0)
      {
        while(rectangleStack.Count() > 0)
        {
          answer = Math.Max(answer, rectangleStack.Peek()[1]*(i-rectangleStack.Peek()[0]+1));
          rectangleStack.Pop();
        }
      }
    }

    return answer;
  }
  
}