笛卡尔树
符合堆和二叉搜索树性质,treap也是一种特殊笛卡尔树
堆性质就是树下层元素的值都小于等于或大于等于上层元素的值
二叉搜索树是一个左儿子小于自身,右儿子大于自身的树,在笛卡尔树中,通常为数组索引
这时候就可以用单调栈来维护右链建树
#include<iostream>
#include<algorithm>
using namespace std;
#define pb push_back
#define LL long long
const int N = 3e5 + 10;
int a[N], n, m, stk[N], k, ls[N], rs[N];
LL ans = 0;
int dfs(int x) {
int siz = 1;
if (ls[x])
siz += dfs(ls[x]);
if (rs[x])
siz += dfs(rs[x]);
ans = max (ans, 1ll * a[x] * siz);
return siz;
}
void solve() {
int top = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
while(k > 0 && a[stk[k]] >= a[i]) k--;
if (k) rs[stk[k]] = i;
if (k < top) ls[i] = stk[k + 1];
stk[++k] = i;
top = k;
}
dfs(stk[1]);
cout << ans << endl;
for (int i = 1; i <= n; i++) ls[i] = rs[i] = 0;
k = ans = 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(1) {
cin >> n;
if (!n) break;
solve();
}
return 0;
}