Problem:
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

Submitted solutions:

code_snippet: #include <iostream>
#include <stack>
#include <vector>
#include <utility>
#define ll long long
using namespace std;

// 自身より左にあって自身より小さい要素が一番最後に出てくるインデックス
vector<int> find_small_left(const vector<ll>& hist){
    stack<pair<ll,int>> s; // pair{height, index}
    vector<int> ret(hist.size());
    s.push(make_pair(-1,-1));
    for(int i=0; i<hist.size();i++){
        if(s.top().first < hist[i]){
            ret[i] = i-1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

vector<int> find_small_right(vector<ll> hist){
    stack<pair<ll,int>> s;
    vector<int> ret(hist.size());
    s.push(make_pair(-1,hist.size()));
    for(int i=hist.size()-1; i>=0;i--){
        if(s.top().first < hist[i]){
            ret[i] = i+1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

ll solve(vector<ll> hist){
    vector<int> left = find_small_left(hist);
    vector<int> right = find_small_right(hist);
    ll ans = 0;
    for(int i=0; i<hist.size(); i++){
        ll tmp = (right[i]-left[i]-1)*hist[i];
        if(ans < tmp){
            ans = tmp;
        }
    }
    return ans;
}

int main(){
    int n;
    cin >> n;
    vector<ll> hist(n);
    for(int i=0; i<n; i++){
        cin >> hist[i];
    }
    cout << solve(hist) << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 7816
final_rank: 14

code_snippet: #include <iostream>
#include <stack>
#include <vector>
#include <utility>
#define ll long long
using namespace std;

// 自身より左にあって自身より小さい要素が一番最後に出てくるインデックス
vector<int> find_small_left(const vector<ll>& hist){
    stack<pair<ll,int>> s; // pair{height, index}
    vector<int> ret(hist.size());
    s.push(make_pair(-1,-1));
    for(int i=0; i<hist.size();i++){
        if(s.top().first < hist[i]){
            ret[i] = i-1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

vector<int> find_small_right(vector<ll> hist){
    stack<pair<ll,int>> s;
    vector<int> ret(hist.size());
    s.push(make_pair(-1,hist.size()));
    for(int i=hist.size()-1; i>=0;i--){
        if(s.top().first < hist[i]){
            ret[i] = i+1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

int solve(vector<ll> hist){
    vector<int> left = find_small_left(hist);
    vector<int> right = find_small_right(hist);
    ll ans = 0;
    for(int i=0; i<hist.size(); i++){
        ll tmp = (right[i]-left[i]-1)*hist[i];
        if(ans < tmp){
            ans = tmp;
        }
    }
    return ans;
}

int main(){
    int n;
    cin >> n;
    vector<ll> hist(n);
    for(int i=0; i<n; i++){
        cin >> hist[i];
    }
    cout << solve(hist) << endl;
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 6620
final_rank: 20

code_snippet: #include <iostream>
#include <stack>
#include <vector>
#include <utility>
using namespace std;

// 自身より左にあって自身より小さい要素が一番最後に出てくるインデックス
vector<int> find_small_left(const vector<int>& hist){
    stack<pair<int,int>> s; // pair{height, index}
    vector<int> ret(hist.size());
    s.push(make_pair(-1,-1));
    for(int i=0; i<hist.size();i++){
        if(s.top().first < hist[i]){
            ret[i] = i-1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

vector<int> find_small_right(vector<int> hist){
    stack<pair<int,int>> s;
    vector<int> ret(hist.size());
    s.push(make_pair(-1,hist.size()));
    for(int i=hist.size()-1; i>=0;i--){
        if(s.top().first < hist[i]){
            ret[i] = i+1;
            s.push(make_pair(hist[i],i));
        }else{
            while(s.top().first>=hist[i]){
                s.pop();
            }
            ret[i] = s.top().second;
            s.push(make_pair(hist[i],i));
        }
    }
    return ret;
}

int solve(vector<int> hist){
    vector<int> left = find_small_left(hist);
    vector<int> right = find_small_right(hist);
    int ans = 0;
    for(int i=0; i<hist.size(); i++){
        int tmp = (right[i]-left[i]-1)*hist[i];
        if(ans < tmp){
            ans = tmp;
        }
    }
    return ans;
}

int main(){
    int n;
    cin >> n;
    vector<int> hist(n);
    for(int i=0; i<n; i++){
        cin >> hist[i];
    }
    cout << solve(hist) << endl;
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 5020
final_rank: 19

code_snippet: // C++ program to find maximum rectangular area in linear time
#include<iostream>
#include<stack>
using namespace std;
 
// The main function to find the maximum rectangular area under given
// histogram with n bars
long long getMaxArea(long long hist[], int n)
{
    // Create an empty stack. The stack holds indexes of hist[] array
    // The bars stored in stack are always in increasing order of their
    // heights.
    stack<long long> s;
 
    long long max_area = 0; // Initalize max area
    long long tp;  // To store top of stack
    long long area_with_top; // To store area with top bar as the smallest bar
 
    // Run through all bars of given histogram
    int i = 0;
    while (i < n)
    {
        // If this bar is higher than the bar on top stack, push it to stack
        if (s.empty() || hist[s.top()] <= hist[i])
            s.push(i++);
 
        // If this bar is lower than top of stack, then calculate area of rectangle 
        // with stack top as the smallest (or minimum height) bar. 'i' is 
        // 'right index' for the top and element before top in stack is 'left index'
        else
        {
            tp = s.top();  // store the top index
            s.pop();  // pop the top
 
            // Calculate the area with hist[tp] stack as smallest bar
            area_with_top = hist[tp] * (s.empty() ? i : i - s.top() - 1);
 
            // update max area, if needed
            if (max_area < area_with_top)
                max_area = area_with_top;
        }
    }
 
    // Now pop the remaining bars from stack and calculate area with every
    // popped bar as the smallest bar
    while (s.empty() == false)
    {
        tp = s.top();
        s.pop();
        area_with_top = hist[tp] * (s.empty() ? i : i - s.top() - 1);
 
        if (max_area < area_with_top)
            max_area = area_with_top;
    }
 
    return max_area;
}
 
// Driver program to test above function
int main()
{
    long long hist[100000];
    int n;
	
	cin >> n;
	
	for(int i = 0; i < n; i++){
		cin >> hist[i];
	}
	
    cout << getMaxArea(hist, n) << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4804
final_rank: 4

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/modint>

using namespace std;
//using namespace atcoder;
using ll = long long;
//using mint = modint998244353;

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    /*
       最大長方形
       stackに(インデックス、高さ)を入れ、stackで広義単調増加になるように高さを管理する。
       番兵として(-∞, 0)を入れておく。
       stackの末尾がA_iより低くなるまでpopする。popできなくなったらそれが高さA_iの長方形の左端となる。
       逆から見てくと右端もわかる。
       [l_i, r_i]が高さA_i以上となる区間なので(r_i-l_i+1)*A_iの長方形が作れる。
    */

    ll N, ans=0;
    cin >> N;
    vector<ll> A(N+1), left(N+1), right(N+1);
    for (int i=1; i<=N; i++) cin >> A[i];
    vector<pair<ll, ll>> v; //どこまでA_i以上の高さが連続するかを管理するstack
    v.push_back({-1e9, 0});
    for (int i=1; i<=N; i++){
        while(v.back().first >= A[i]) v.pop_back();
        left[i] = v.back().second+1;
        v.push_back({A[i], i});
    }
    v.clear();
    v.push_back({-1e9, N+1});
    for (int i=N; i>=1; i--){
        while(v.back().first >= A[i]) v.pop_back();
        right[i] = v.back().second-1;
        v.push_back({A[i], i});
    }

    for (int i=1; i<=N; i++) ans = max(ans, A[i]*(right[i]-left[i]+1));
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7544
final_rank: 2

code_snippet: #include<iostream>
#include<vector>
using namespace std;
int main() {
  int N;
  cin >> N;
  vector<int> h(N);
  for (int i = 0; i < N; i++) {
    cin >> h[i];
  }
  vector<pair<long long, int>> st;
  //st(高さ, idx)idxは左端を入れる
  long long ans = 0;
  for (int i = 0; i < N; i++) {
    int last = i;
    //[h[i]より大きい値のidx, i)の区間の長方形を計算する。そしてその飛び出たやつは消す
    while (!st.empty() && st.back().first > h[i]) {
      ans = max(ans, st.back().first * (i - st.back().second));
      last = st.back().second;
      st.pop_back();
    }
    if (st.empty() || st.back().first <= h[i]) {
      //st.back().first == h[i]のときは，左端のみが分かればいいため入れない。
      //lastは左端になっている。
      st.push_back(make_pair(h[i], last));
    }
  }  
  while (!st.empty()) {
    ans = max(ans, st.back().first * (N - st.back().second));
    st.pop_back();
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 5460
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
template<typename T, typename F>
class CartesianTree {
  private:
    int N;
    F op;
    vector<int> left, right;
    vector<T> A;
  public:
    int root;
    vector<vector<int>> E;//2分木を構築
    vector<int> par;
    CartesianTree() {}
    CartesianTree(F _op, const vector<T> _A) 
    : A(_A), op(_op), N(_A.size()), left(_A.size()), right(_A.size()), E(_A.size()) {
      vector<int> st;
      par.resize(N, -1);
      for (int i = 0; i < N; i++) {
        int pre = -1;
        while (!st.empty() && op(A[st.back()], A[i])) {
          pre = st.back();
          st.pop_back();
        }
        if (pre != -1) {
          par[pre] = i;
        }
        if (!st.empty()) {
          par[i] = st.back();
        } else {
          root = i;
        }
        st.push_back(i);
      }
      for (int i = 0; i < N; i++) {
        if (par[i] != -1) {
          E[par[i]].push_back(i);
        }
      }
      calc();
    }  
    void calc() {
      for (int i = 0; i < N; i++) {
        left[i] = i;
        right[i] = i + 1;
      }
      auto dfs = [&] (auto &&self, int v) -> void {
        for (int w : E[v]) {
          self(self, w);
          left[v] = min(left[v], left[w]);
          right[v] = max(right[v], right[w]);
        }
      };
      dfs(dfs, root);
    }
    //A[v]が最大値または最小値(opによる)を取る区間を[l ,r)で返す
    pair<int, int> get_range(int v) {
      return make_pair(left[v], right[v]);
    }
};
bool op(int a, int b) {
  return a > b;
}
int main() {
  int N;
  cin >> N;
  vector<int> h(N);
  for (int i = 0; i < N; i++) {
    cin >> h[i];
  }
  CartesianTree CT(op, h);
  long long ans = 0;
  for (int i = 0; i < N; i++) {
    auto [l, r] = CT.get_range(i);
    ans = max(ans, (long long)(r - l) * h[i]);
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 17544
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define INF 1e18
int main(){
    
    ll n,f,ans=0,sub;
    cin>>n;
    vector<ll> h(n);
    stack<pair<ll,ll>> s;
    for(auto& i:h)cin>>i;
    for(ll i=0;i<n;i++){
        if(s.empty()||s.top().first<h[i]){
            s.push({h[i],1});
            ans=max(ans,s.top().first);
        }
        else{
            f=0,sub=INF;
            while(s.size()&&s.top().first>=h[i]){
                f+=s.top().second;
                sub=min(sub,s.top().first);
                ans=max(ans,sub*f);
                s.pop();
            }
            s.push({h[i],f+1});
            ans=max(ans,s.top().first*(f+1));
        }
    }f=0,sub=INF;
    while(s.size()){
        auto [i,j]=s.top();s.pop();
        f+=j;
        if(s.empty())break;
        if(s.top().first<=i){
            ans=max(ans,s.top().first*(s.top().second+f));
        }
        else break;
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 5176
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
long long int h[100005],l[100005],r[100005];
stack<int>sl;
stack<int>sr;
int main(){
	int n;
	cin>>n;
	int i;
	for(i=1;i<=n;i++){
		cin>>h[i];
	}
	for(i=1;i<=n;i++){
		while(!sl.empty()&&h[sl.top()]>=h[i]){
			sl.pop();
		}
		if(sl.empty()){
			l[i]=0;
		}else{
			l[i]=sl.top();
		}
		sl.push(i);
	}
	for(i=n;i>=1;i--){
		while(!sr.empty()&&h[sr.top()]>=h[i]){
			sr.pop();
		}
		if(sr.empty()){
			r[i]=n+1;
		}else{
			r[i]=sr.top();
		}
		sr.push(i);
	}
	long long int ans=0;
	for(i=1;i<=n;i++){
		ans=max(ans,h[i]*(r[i]-l[i]-1));
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 6204
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
#include <chrono>
#include <complex>
#include <cmath>
//#define PI M_PI
#include <unistd.h>
#define pc_u putchar
#pragma GCC target ("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#define rep(i,a,b) for(it i=(it)(a);i<=(it)b;i++)
#define rep2(i,a,b,c) for(it i=(it)(a);i<=(it)b;i+=(it)c)
#define irep(i,a,b) for(int i=(int)(a);i<=(int)b;i++)
#define irep2(i,a,b,c) for(int i=(int)(a);i<=(int)b;i+=c)
#define nrep(i,a,b) for(it i=(it)(a);i>=(it)b;i--)
#define inrep(i,a,b) for(int i=(int)(a);i>=(int)b;i--)
#define inrep2(i,a,b,c) for(int i=(int)(a);i>=(int)b;i-=c)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define Min(x) *min_element(all(x))
#define Max(x) *max_element(all(x))
#define moda 998244353LL
#define modb 1000000007LL
#define modc 968244353LL
#define dai 2502502502502502502LL
#define sho -dai
#define aoi 1e18+1e6
#define giri 1010000000
#define en 3.14159265358979
#define eps 1e-14
#define fi first
#define se second
#define elif else if
template<typename T> using pq=priority_queue<T>;
template<typename T> using pqg=priority_queue<T,vector<T>,greater<T>>;
#define uni(a) a.erase(unique(all(a)),a.end())
using it=long long;
using itn=int;
using un=unsigned long long;
using idb=double;
using db=long double;
using st=string;
using ch=char;
using bo=bool;
using P=pair<it,it>;
using ip=pair<int,int>;
using vi=vector<it>;
using ivi=vector<int>;
using ivd=vector<idb>;
using vd=vector<db>;
using vs=vector<st>;
using vc=vector<ch>;
using vb=vector<bo>;
using vp=vector<P>;
using ivp=vector<ip>;
using sp=set<P>;
using isp=set<ip>;
using ss=set<st>;
using sca=set<ch>;
using si=set<it>;
using isi=set<int>;
using svi=set<vi>;
using vvi=vector<vi>;
using ivvi=vector<ivi>;
using ivvd=vector<ivd>;
using vvd=vector<vd>;
using vvs=vector<vs>;
using vvb=vector<vb>;
using vvc=vector<vc>;
using vvp=vector<vp>;
using ivvp=vector<ivp>;
using vsi=vector<si>;
using ivsi=vector<isi>;
using isvi=set<ivi>;
using vsp=vector<sp>;
using ivsp=vector<isp>;
using vvsi=vector<vsi>;
using ivvsi=vector<ivsi>;
using vvsp=vector<vsp>;
using ivvsp=vector<ivsp>;
using svvb=set<vvb>;
using vvvi=vector<vvi>;
using ivvvi=vector<ivvi>;
using ivvvd=vector<ivvd>;
using vvvd=vector<vvd>;
using vvvb=vector<vvb>;
using ivvvp=vector<ivvp>;
using vvvvi=vector<vvvi>;
using ivvvvi=vector<ivvvi>;
using vvvvd=vector<vvvd>;
using ivvvvvi=vector<ivvvvi>;
using ivvvvvvi=vector<ivvvvvi>;
using ivvvvvvvi=vector<ivvvvvvi>;
const int dx[8]={0,1,0,-1,1,1,-1,-1};
const int dy[8]={1,0,-1,0,1,-1,1,-1};
st abc="abcdefghijklmnopqrstuvwxyz";
st ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
st num="0123456789";
st mb="xo";
st MB="XO";
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
namespace {
 
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
 
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  int s = (int)v.size();
  for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}
 
istream &operator>>(istream &is, __int128_t &x) {
  string S;
  is >> S;
  x = 0;
  int flag = 0;
  for (auto &c : S) {
    if (c == '-') {
      flag = true;
      continue;
    }
    x *= 10;
    x += c - '0';
  }
  if (flag) x = -x;
  return is;
}
 
istream &operator>>(istream &is, __uint128_t &x) {
  string S;
  is >> S;
  x = 0;
  for (auto &c : S) {
    x *= 10;
    x += c - '0';
  }
  return is;
}
 
ostream &operator<<(ostream &os, __int128_t x) {
  if (x == 0) return os << 0;
  if (x < 0) os << '-', x = -x;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
  if (x == 0) return os << 0;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}
 
void input() {}
template <typename T, class... U>
void input(T &t, U &...u) {
  cin >> t;
  input(u...);
}
template <typename T, class... U>
void input1(T &t, U &...u) {
  input(u...);
}
void print() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void print(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u)) cout << sep;
  print(u...);
}
template <typename T, class... U, char sep = ' '>
void print1(const T &t, const U &...u) {
  if (sizeof...(u)) cout << sep;
  print(u...);
}
 
struct IoSetupNya {
  IoSetupNya() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(7);
  }
} iosetupnya;
 
}  //namespace Nyaan

template<typename T>
T Sum(vector<T> &a){
  T s=0;
  for(auto i:a)s+=i;
  return s;
}

template<typename T>
void dec(vector<T> &a){
  rep(i,0,a.size()-1)a[i]--;
  return;
}

template<typename T>
T gcda(T a,T b){
  if(!a||!b)return max(a,b);
  while(a%b&&b%a){
    if(a>b)a%=b;
    else b%=a;
  }
  return min(a,b);
}

it lcma(it a,it b){
  return a/gcda(a,b)*b;
}

db distance(db a,db b,db c,db d){return sqrt((a-c)*(a-c)+(b-d)*(b-d));}

bo outc(int h,int w,int x,int y){
  return (x<0||x>=h||y<0||y>=w);
}

template<typename T>
vector<vector<T>> nep(vector<T> a){
  vector<vector<T>> e;
  sort(all(a));
  do{
    e.emplace_back(a);
  }while(next_permutation(all(a)));
  return e;
}

void yn(bo a){print(a?string("Yes"):string("No"));}
void YN(bo a){print(a?string("YES"):string("NO"));}

/*総和をもとめるセグ木
struct nod{
  it val;
  nod(it v=0):val(v){}
};
 
nod op(nod a,nod b){return nod(a.val+b.val);}
nod e(){return nod(0);}
 
struct act{
  it a;
  act(it e=0):a(e){}
};
 
nod mapping(act f,nod x){return nod(f.a+x.val);}
act comp(act f,act g){return act(f.a+g.a);}
act id(){return act(0);}*/
//#define endl '\n'
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

struct dsu1{
  ivi par,siz,mi,ma;
  dsu1(int n){
    init(n);
  }
  void init(int n){
    rep(i,0,n-1){
      par.emplace_back(i);
      siz.emplace_back(1);
    }
  }
  int leader(int u){
    if(par[u]==u)return u;
    return par[u]=leader(par[u]);
  }
  void merge(int u,int v){
    int ru=leader(u),rv=leader(v);
    if(ru==rv)return;
    if(size(ru)<size(rv))swap(ru,rv);
    siz[ru]+=siz[rv];
    par[rv]=ru;
  }
  bool same(int u,int v){
    return leader(u)==leader(v);
  }
  int size(int u){
    return siz[leader(u)];
  }
};

void solve(){
  int n;input(n);
  pq<P> que;
  vi h(n);
  irep(i,0,n-1){
    input(h[i]);
    que.push({h[i],i});
  }
  it ans=0;
  dsu1 uf(n);
  while(que.size()){
    it w=que.top().first;int u=que.top().second;que.pop();
    if(u&&h[u-1]>=h[u])uf.merge(u-1,u);
    if(u!=n-1&&h[u+1]>=h[u])uf.merge(u+1,u);
    ans=max(ans,w*uf.size(u));
  }
  print(ans);
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int t=1;//input(t);
  while(t--)solve();
}
accuracy: 1
time_ms: 20
memory_kb: 6776
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=(l);i<(r);i++)
using ll=long long;
template<typename T1,typename T2>inline bool chmin(T1 &a,T2 b){ return (a>b?a=b,true:false); }
template<typename T1,typename T2>inline bool chmax(T1 &a,T2 b){ return (a<b?a=b,true:false); }

int main(){
    cin.tie(nullptr)->ios::sync_with_stdio(false); 
    int n;
    cin>>n;
    vector<int> a(n);
    for(auto &e:a) cin>>e;
    vector<int> L(n),R(n);
    stack<pair<int,int>> st;
    st.emplace(-1,-1);
    rep(i,0,n){
        while(st.top().first>=a[i]) st.pop();
        L[i]=i-st.top().second-1;
        st.emplace(a[i],i);
    }
    while(st.size()) st.pop();
    st.emplace(-1,n);
    for(int i=n-1;i>=0;i--){
        while(st.top().first>=a[i]){
            st.pop();
        }
        R[i]=st.top().second-i-1;
        st.emplace(a[i],i);
    }
    ll ans=0;
    rep(i,0,n){
        chmax(ans,(ll)a[i]*(L[i]+R[i]+1));
    }
    cout<<ans<<"\n";
}
accuracy: 1
time_ms: 10
memory_kb: 5088
final_rank: 1

code_snippet: #include <iostream>
#include <stack>
#include <vector>
using namespace std;

long long largest(const vector<int> &height)
{
    int n = height.size();
    stack<int> s;
    long long max_area = 0;
    for (int i = 0; i < n; ++i)
    {
        int h = height[i];
        while (!s.empty() && height[s.top()] >= h)
        {
            long long h = height[s.top()];
            s.pop();
            long long w;
            if (s.empty())
                w = i;
            else
                w = i - s.top() - 1;
            max_area = max(max_area, h * w);
        }
        s.push(i);
    }
    return max_area;
}

int main()
{
    int N;
    cin >> N;
    vector<int> height(N+1);
    for (int i = 0; i < N; ++i)
        cin >> height[i];
    height[N] = 0;
    cout << largest(height) << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3736
final_rank: 3

code_snippet: #include <iostream>
#include <stack>
#include <vector>
using namespace std;

int largest(const vector<int> &height)
{
    int n = height.size();
    stack<int> s;
    long long max_area = 0;
    for (int i = 0; i < n; ++i)
    {
        int h = height[i];
        while (!s.empty() && height[s.top()] >= h)
        {
            long long h = height[s.top()];
            s.pop();
            long long w;
            if (s.empty())
                w = i;
            else
                w = i - s.top() - 1;
            max_area = max(max_area, h * w);
        }
        s.push(i);
    }
    return max_area;
}

int main()
{
    int N;
    cin >> N;
    vector<int> height(N+1);
    for (int i = 0; i < N; ++i)
        cin >> height[i];
    height[N] = 0;
    cout << largest(height) << endl;
    return 0;
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 3820
final_rank: 17

code_snippet: #include <iostream>
#include <stack>
#include <vector>
using namespace std;

int largest(const vector<int> &height)
{
    int n = height.size();
    stack<int> s;
    int max_area = 0;
    for (int i = 0; i < n; ++i)
    {
        int h = height[i];
        while (!s.empty() && height[s.top()] > h)
        {
            int h = height[s.top()];
            s.pop();
            int w;
            if (s.empty())
                w = i;
            else
                w = i - s.top() - 1;
            max_area = max(max_area, h * w);
        }
        s.push(i);
    }
    return max_area;
}

int main()
{
    int N;
    cin >> N;
    vector<int> height(N+1);
    for (int i = 0; i < N; ++i)
        cin >> height[i];
    height[N] = 0;
    cout << largest(height) << endl;
    return 0;
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 3752
final_rank: 16

code_snippet: #include <iostream>
#include <stack>
#include <vector>
using namespace std;

int largest(const vector<int> &height)
{
    int n = height.size();
    stack<int> s;
    int max_area = 0;
    for (int i = 0; i <= n; ++i)
    {
        int h = height[i];
        while (!s.empty() && height[s.top()] > h)
        {
            int h = height[s.top()];
            s.pop();
            int w;
            if (s.empty())
                w = i;
            else
                w = i - s.top() - 1;
            max_area = max(max_area, h * w);
        }
        s.push(i);
    }
    return max_area;
}

int main()
{
    int N;
    cin >> N;
    vector<int> height(N+1);
    for (int i = 0; i < N; ++i)
        cin >> height[i];
    height[N] = 0;
    cout << largest(height) << endl;
    return 0;
}
accuracy: 0.6666666666666666
time_ms: 10
memory_kb: 3876
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define repp(i,n) for(int i = 1; i <= (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define srep(i,s,t) for (int i = s; i < (t); ++i)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define koulet srand((unsigned)clock()+(unsigned)time(NULL));
#define newline puts("")
#define vc vector
#define stoi stoll 
using namespace std;
template<class T> using vv = vc<vc<T>>;
template<class T> using PQ = priority_queue<T,vc<T>,greater<T>>;
using uint = unsigned; using ull = unsigned long long;
using vi = vc<int>; using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long; using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>;
using P = pair<int,int>; using vp = vc<P>; using vvp = vv<P>; using LP = pair<ll,ll>;
using vs = vc<string>; using vb=vc<bool> ; using vlp = vc<LP> ; 
int geti(){int x;scanf("%d",&x);return x;}
vi pm(int n, int s=0) { vi a(n); iota(rng(a),s); return a;}
template<class T1,class T2>istream& operator>>(istream&i,pair<T1,T2>&v){return i>>v.fi>>v.se;}
template<class T1,class T2>ostream& operator<<(ostream&o,const pair<T1,T2>&v){return o<<v.fi<<","<<v.se;}
template<class T>istream& operator>>(istream&i,vc<T>&v){rep(j,sz(v))i>>v[j];return i;}
template<class T>string join(const T&v,const string&d=""){stringstream s;rep(i,sz(v))(i?s<<d:s)<<v[i];return s.str();}
template<class T>ostream& operator<<(ostream&o,const vc<T>&v){if(sz(v))o<<join(v," ");return o;}
template<class T>void vin(vc<T>&a){int n;cin>>n;a=vc<T>(n);cin>>a;}
template<class T>void vin(vv<T>&a){int n,m;cin>>n>>m;a=vv<T>(n,vc<T>(m));cin>>a;}
template<class T1,class T2>void operator--(pair<T1,T2>&a,int){a.fi--;a.se--;}
template<class T1,class T2>void operator++(pair<T1,T2>&a,int){a.fi++;a.se++;}
template<class T>void operator--(vc<T>&a,int){for(T&x:a)x--;}
template<class T>void operator++(vc<T>&a,int){for(T&x:a)x++;}
template<class T>void operator+=(vc<T>&a,T b){for(T&x:a)x+=b;}
template<class T>void operator-=(vc<T>&a,T b){for(T&x:a)x-=b;}
template<class T>void operator*=(vc<T>&a,T b){for(T&x:a)x*=b;}
template<class T>void operator/=(vc<T>&a,T b){for(T&x:a)x/=b;}
template<class T>void operator+=(vc<T>&a,const vc<T>&b){a.insert(a.end(),rng(b));}
template<class T1,class T2>pair<T1,T2>operator+(const pair<T1,T2>&a,const pair<T1,T2>&b){return {a.fi+b.fi,a.se+b.se};}
template<class T1,class T2>pair<T1,T2>operator-(const pair<T1,T2>&a,const pair<T1,T2>&b){return {a.fi-b.fi,a.se-b.se};}
template<class T>pair<T,T>operator*(const pair<T,T>&a,T b){return {a.fi*b,a.se*b};}
template<class T1,class T2>bool mins(T1& x,const T2&y){if(y<x){x=y;return true;}else return false;}
template<class T1,class T2>bool maxs(T1& x,const T2&y){if(x<y){x=y;return true;}else return false;}
template<class T>T min(const vc<T>&a){return *min_element(rng(a));}
template<class T>T max(const vc<T>&a){return *max_element(rng(a));}
template<class Tx,class Ty>Tx dup(Tx x, Ty y){return (x+y-1)/y;}
template<class T>ll suma(const vc<T>&a){ll s=0;for(auto&&x:a)s+=x;return s;}
template<class T>ll suma(const vv<T>&a){ll s=0;for(auto&&x:a)s+=suma(x);return s;}
template<class T>void uni(T&a){sort(rng(a));a.erase(unique(rng(a)),a.end());}
template<class T>void prepend(vc<T>&a,const T&x){a.insert(a.begin(),x);}
template<typename T>T floor(T a, T b){T r=(a%b+b)%b;return (a-r)/b;}
template<typename T>T ceil(T a, T b){return floor(a+b-1,b);}
template<typename T>vc<T> cumsum(vc<T> &a,int off=1){int N=sz(a);vc<T>B(N+1);rep(i, N)B[i+1]=a[i]+B[i];if(off==0)B.erase(B.begin());return B;}
const double eps = 1e-10;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
#define dame { puts("-1"); return 0 ;}
#define yes { puts("Yes"); return 0 ;}
#define no { puts("No"); return 0 ;}
#define rtn(x) { cout<<(x)<<endl;} // flush!
#define yn {puts("Yes");}else{puts("No");}
ll c2(ll n) { return n*(n-1)>>1;}

template<typename T>void rot(T& a,int i){rotate(a.begin(),a.begin()+(i),a.end());}// i回シフト
template<typename T>void rot(vv<T>& a){int h=sz(a),w=sz(a[0]);vv<T> p(w,vc<T>(h));swap(a,p);rep(i,h)rep(j,w)a[j][h-1-i]=p[i][j];}
void rot(vc<string>& a){int h=sz(a),w=sz(a[0]);vc<string> p(w,string(h,'?'));swap(a,p);rep(i,h)rep(j,w)a[j][h-1-i]=p[i][j];}

const int dx[] = {-1,0,1,0,1,1,-1,-1,}, dy[] = {0,-1,0,1,1,-1,1,-1}; //^<v>↘︎
//^, <, v, >, ↘︎, ↙︎, ↗︎, ↖︎ 

// Mod int
uint mod = 998244353;//*/
// uint mod = 1000000007;//*/
uint md(ll x) { x%=mod; return x<0?x+mod:x;}
ll md(ll x, ll m) { x%=m; return x<0?x+m:x;}
struct mint {
  uint x;
  mint(): x(0) {}
  mint(ll x):x(md(x)) {}
  mint operator-() const { return mint(0) - *this;}
  mint operator~() const { return mint(1) / *this;}
  mint& operator+=(const mint& a) { if((x+=a.x)>=mod) x-=mod; return *this;}
  mint& operator-=(const mint& a) { if((x+=mod-a.x)>=mod) x-=mod; return *this;}
  mint& operator*=(const mint& a) { x=(ull)x*a.x%mod; return *this;}
  mint& operator/=(const mint& a) { x=(ull)x*a.pow(mod-2).x%mod; return *this;}
  mint operator+(const mint& a) const { return mint(*this) += a;}
  mint operator-(const mint& a) const { return mint(*this) -= a;}
  mint operator*(const mint& a) const { return mint(*this) *= a;}
  mint operator/(const mint& a) const { return mint(*this) /= a;}
  mint pow(ll t) const {
    mint res = 1; for (mint p=x;t;p*=p,t>>=1) if (t&1) res *= p; return res;
  }
  mint ppow(ll t) const { int p=mod-1; return pow((t%p+p)%p);}
  bool operator<(const mint& a) const { return x < a.x;}
  bool operator==(const mint& a) const { return x == a.x;}
  bool operator!=(const mint& a) const { return x != a.x;}
};
mint ex(mint x, ll t) { return x.pow(t);}
istream& operator>>(istream&i,mint&a) {i>>a.x;return i;}
//*
ostream& operator<<(ostream&o,const mint&a) {o<<a.x;return o;}
/*/
ostream& operator<<(ostream&o, const mint&x) {
  int a = x.x, b = 1;
  rep(s,2)rep1(i,1000) {
    int y = ((s?-x:x)*i).x; if (abs(a)+b > y+i) a = s?-y:y, b = i;
  }
  o<<a; if (b != 1) o<<'/'<<b; return o;
}//*/
using vm = vector<mint>;
using vvm = vector<vm>;
struct modinv {
  int n; vm d;
  modinv(): n(2), d({0,1}) {}
  mint operator()(int i) { while (n <= i) d.pb(-d[mod%n]*(mod/n)), ++n; return d[i];}
  mint operator[](int i) const { return d[i];}
} invs;
struct modfact {
  int n; vm d;
  modfact(): n(2), d({1,1}) {}
  mint operator()(int i) { while (n <= i) d.pb(d.back()*n), ++n; return d[i];}
  mint operator[](int i) const { return d[i];}
} facs;
struct modfactinv {
  int n; vm d;
  modfactinv(): n(2), d({1,1}) {}
  mint operator()(int i) { while (n <= i) d.pb(d.back()*invs(n)), ++n; return d[i];}
  mint operator[](int i) const { return d[i];}
} ifacs;
mint comb(int a, int b) {
  if (a < b || b < 0) return 0;
  return facs(a)*ifacs(b)*ifacs(a-b);
}
struct modpow {
  mint x; int n; vm d;
  modpow(mint x=2): x(x), n(1), d(1,1) {}
  mint operator()(int i) { while (n <= i) d.pb(d.back()*x), ++n; return d[i];}
  mint operator[](int i) const { return d[i];}
} two(2);//, owt(invs(2));
// 

ll largest_rectangle(vl a){
	int n = sz(a) ;
	ll res = 0 ;
	vl l(n) , r(n) ;
	{
		stack<int> st; 
		rep(i, n){
			while(sz(st)&&a[st.top()]>=a[i]) st.pop() ;
			if(sz(st) == 0) l[i] = i+1 ; 
			else l[i]=i-st.top() ;
			st.push(i) ;
		}
	};
	{
		stack<int> st; 
		drep(i, n){
			while(sz(st)&&a[st.top()]>a[i]) st.pop() ;
			if(sz(st) == 0) r[i]=n-i; 
			else r[i]=st.top()-i;
			st.push(i) ;
		}
	};
	rep(i, n) maxs(res, (ll)a[i]*(r[i]+l[i]-1)) ;
	return res ;
} ;
int main() {
	int n; cin>>n ; 
	vl h(n) ;cin>> h ; 
	cout << largest_rectangle(h) << endl;





	


  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6740
final_rank: 12

code_snippet: #define rep(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(v) v.begin(),v.end()
typedef long long ll;

#include <bits/stdc++.h>
using namespace std;

//最大長方形(ヒストグラム）　蟻本p.298 計算量O(n)
int main(){
  int n;
  cin>>n;
  
  vector<ll> H(n);
  rep(i,n) cin>>H[i];
  
  vector<ll> L(n),R(n); //i番目の高さで行ける左端と右端
  stack<ll> s,t;
  
  //行ける候補をスタックで管理。i番目の高さ以上の場所は今後、端(のひとつ左)にならないので削除。
  rep(i,n){
    while(!s.empty() && H[s.top()]>=H[i]) s.pop();
    if(s.empty()) L[i]=0;
    else L[i]=s.top()+1;
    s.push(i);
  }
  for(int i=n-1;i>=0;i--){
    while(!t.empty() && H[t.top()]>=H[i]) t.pop();
    if(t.empty()) R[i]=n-1;
    else R[i]=t.top()-1;
    t.push(i);
  }
  
  ll ma=0;
  rep(i,n) ma=max(ma,H[i]*(R[i]-L[i]+1));
  cout<<ma<<endl;
  
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 6148
final_rank: 10

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;

/* alias*/
using ull = unsigned long long;
using ll = long long;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vb = vector<bool>;
using vd = vector<double>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using vvd = vector<vd>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;

/* define short */
#define _overload5(a, b, c, d, e, name, ...) name
#define _overload4(a, b, c, d, name, ...) name
#define _overload3(a, b, c, name, ...) name
#define _rep0(n) for(int i = 0; i < (int)(n); ++i)
#define _rep1(i, n) for(int i = 0; i < (int)(n); ++i)
#define _rep2(i, a, b) for(int i = (int)(a); i < (int)(b); ++i)
#define _rep3(i, a, b, c) for(int i = (int)(a); i < (int)(b); i += (int)(c))
#define rep(...) _overload4(__VA_ARGS__, _rep3, _rep2, _rep1, _rep0)(__VA_ARGS__)
#define rrep1(n) for(int i = (n) - 1;i >= 0;i--)
#define rrep2(i,n) for(int i = (n) - 1;i >= 0;i--)
#define rrep3(i,a,b) for(int i = (b) - 1;i >= (a);i--)
#define rrep4(i,a,b,c) for(int i = (a) + ((b)-(a)-1) / (c) * (c);i >= (a);i -= c)
#define rrep(...) _overload4(__VA_ARGS__, rrep4, rrep3, rrep2, rrep1)(__VA_ARGS__)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define sz(x) (int)(x).size()
#define pcnt(x) __builtin_popcountll(x)
#define eb emplace_back
#define fi first
#define se second

/* debug */
// 標準エラー出力を含む提出はrejectされる場合もあるので注意
#define debug(x) cerr << "\033[33m(line:" << __LINE__ << ") " << #x << ": " << x << "\033[m" << endl;

/* func */
template<class T> inline bool chmax(T& a, T b) { return ((a < b) ? (a = b, true) : (false)); }
template<class T> inline bool chmin(T& a, T b) { return ((a > b) ? (a = b, true) : (false)); }

/* const */
const int INF = INT_MAX/2;
const ll LINF = 1LL<<60;
const int MOD = 1e9+7;
const int dx[] {1,0,-1,0};
const int dy[] {0,1,0,-1};
const double PI = 3.1415926535;
const string yes = "Yes";
const string no = "No";


int main() { 
  int n; cin >> n;
  vl a(n+1); rep(i,n) cin >> a[i];

  ll ans = 0;
  vector<pair<ll,int>> st;
  rep(i,n+1) {
    int pos = i;
    while (!st.empty() && st.back().fi > a[i]) {
      auto [h,j] = st.back(); st.pop_back();
      ll x = h*(i-j);
      chmax(ans,x);
      pos = j;
    }
    st.eb(a[i],pos);
  }

  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5984
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <stack>
using namespace std;
typedef long long ll;
// const ll INF64 = 1LL << 60;
const ll INF64 = ((1LL<<62)-(1LL<<31));  // 10^18より大きく、かつ2倍しても負にならない数
const int INF32 = 0x3FFFFFFF;  // =(2^30)-1 10^9より大きく、かつ2倍しても負にならない数
template<class T> inline bool chmin(T &a, T b) { if(a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T &a, T b) { if(a < b) { a = b; return true; } return false; }
#define YesNo(T) cout << ((T) ? "Yes" : "No") << endl;  // T:bool

// https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_C

/*
 * ヒストグラム中の最大正方形問題。
 * 考え方は以下が分かりやすかった。
 *   http://algorithms.blog55.fc2.com/blog-entry-132.html
 * 
 * スタックに {y座標:h[i], x座標} の形で、y座標について単調増加になるよう持たせていく。
 * 今見ているh[i]をスタックに入れようとしたとき、単調増加を満たさないのであれば取り出して面積を計算する。
 * 
 * スタックに登録するとき、取り出した分だけx座標を手前に動かす必要がある点に注意。
 */

int main(void)
{
	int i;
	int N; cin >> N;
	vector<ll> h(N); for(i = 0; i < N; i++) {cin >> h[i];}
	h.push_back(0);  // 末尾番兵

	// [実装方針]
	// stack内は単調増加、先頭から見ていく、stackには高さに加えx座標の情報が必要

	stack<pair<ll,ll>> st;
	st.push({0, -1});  // 先頭番兵
	ll ans = 0;
	for(i = 0; i < (int)h.size(); i++)
	{
		int x = i;
		while(st.top().first > h[i])  // h[i]を入れたときに単調増加を満たすようにするまで
		{
			auto [hh,xx] = st.top();
			st.pop();
			chmax(ans, (i-xx)*hh);
			x = xx;
		}
		st.push({h[i], x});
	}
	cout << ans << endl;

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5488
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <stack>
using namespace std;
typedef long long ll;
// const ll INF64 = 1LL << 60;
const ll INF64 = ((1LL<<62)-(1LL<<31));  // 10^18より大きく、かつ2倍しても負にならない数
const int INF32 = 0x3FFFFFFF;  // =(2^30)-1 10^9より大きく、かつ2倍しても負にならない数
template<class T> inline bool chmin(T &a, T b) { if(a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T &a, T b) { if(a < b) { a = b; return true; } return false; }
#define YesNo(T) cout << ((T) ? "Yes" : "No") << endl;  // T:bool

// https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_3_C

/*
 * 
 * 
 */

int main(void)
{
	int i;
	int N; cin >> N;
	vector<ll> h(N); for(i = 0; i < N; i++) {cin >> h[i];}
	h.push_back(0);  // 末尾番兵

	// stack内は単調増加
	// stackには高さとx座標の情報が必要
	// 先頭から
	stack<pair<ll,ll>> st;
	st.push({0, -1});  // 番兵
	ll ans = 0;
	for(i = 0; i < (int)h.size(); i++)
	{
		int x = i;
		while(st.top().first > h[i])  // h[i]を入れても単調増加を満たすようにするまで
		{
			auto [hh,xx] = st.top();
			st.pop();
			chmax(ans, (i-xx)*hh);
			x = xx;
		}
		// delete
		st.push({h[i], x});
	}
	cout << ans << endl;

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 5364
final_rank: 6