Algorithms notes - Cartesian tree template

See: OI-the Wi
template:

const int N = 3e6 + 10;
struct Node {
    int id, val, par, ch[2], sz;
    inline bool operator < (Node & rhs) {return id < rhs.id;}
    inline void init(int _id, int _val, int _par) {
        id = _id, val = _val, par = _par, ch[0] = ch[1] = 0, sz = 1;
    }
}tree[N];
inline int cartesian_build(int n) {
    for (int i = 1; i <= n; ++i) {
        int k = i-1;
        while(tree[k].val > tree[i].val) k = tree[k].par;
        tree[i].ch[0] = tree[k].ch[1];
        tree[tree[i].ch[0]].par = i;
        tree[k].ch[1] = i;
        tree[i].par = k;
    }
    return tree[0].ch[1];
}

Example: LightOJ - 1083
Code:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb emplace_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head

const int N = 3e4 + 10;
struct Node {
    int id, val, par, ch[2], sz;
    bool operator < (Node & rhs) {return id < rhs.id;}
    void init(int _id, int _val, int _par) {
        id = _id, val = _val, par = _par, ch[0] = ch[1] = 0, sz = 1;
    }
}tree[N];
int cartesian_build(int n) {
    for (int i = 1; i <= n; ++i) {
        int k = i-1;
        while(tree[k].val > tree[i].val) k = tree[k].par;
        tree[i].ch[0] = tree[k].ch[1];
        tree[tree[i].ch[0]].par = i;
        tree[k].ch[1] = i;
        tree[i].par = k;
    }
    return tree[0].ch[1];
}
LL ans;
void dfs(int u) {
    if(tree[u].ch[0]) dfs(tree[u].ch[0]), tree[u].sz += tree[tree[u].ch[0]].sz;
    if(tree[u].ch[1]) dfs(tree[u].ch[1]), tree[u].sz += tree[tree[u].ch[1]].sz;
    ans = max(ans, tree[u].sz*1LL*tree[u].val);
}
int T, n, a[N], rt;
int main() {
    scanf("%d", &T);
    for (int cs = 1; cs <= T; ++cs) {
        scanf("%d", &n);
        tree[0].init(0, 0, 0);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), tree[i].init(i, a[i], 0);
        rt = cartesian_build(n);
        ans = 0, dfs(rt);
        printf("Case %d: %lld\n", cs, ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/widsom/p/11258675.html