笛卡尔树

板子题

符合堆和二叉搜索树性质,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;
}
posted @ 2024-11-27 10:40  lyrrr  阅读(4)  评论(0编辑  收藏  举报