洛谷P13037 [GCJ 2021 #2] Hidden Pancakes 题解 笛卡尔树

题目链接:https://www.luogu.com.cn/problem/P13037

解题思路完全来自 qiuqiu_luogu大佬的博客 。虽然大佬的博客中并没有使用笛卡尔树,但是基于大佬的想法建树然后解决这题也很方便。

示例程序:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
const int maxn = 1e5 + 5;

int T, n, a[maxn], ls[maxn], rs[maxn], rt;
ll fac[maxn], ans;

void init() {
    fac[0] = 1;
    for (int i = 1; i < maxn; i++)
        fac[i] = fac[i-1] * i % mod;
}

ll qpow(ll a, ll b) {
    ll res = 1;
    for (ll t = a % mod; b; t = t * t % mod, b >>= 1) {
        if (b & 1ll)
            (res *= t) %= mod;
    }
    return res;
}

ll inv(ll a) {
    return qpow(a, mod-2);
}

ll C(int n, int m) {
    if (m > n) return 0;
    return fac[n] * inv(fac[m]) % mod * inv(fac[n-m]) % mod;
}

void dfs(int u, int l, int r) {
    if (l > r) return;
    (ans *= C(r-l, u-l)) %= mod;
    dfs(ls[u], l, u-1);
    dfs(rs[u], u+1, r);
}

void cal() {
    ans = 0;
    if (a[1] != 1) return;
    for (int i = 1; i < n; i++)
        if (a[i] + 1 < a[i+1])
            return;
    fill(ls+1, ls+n+1, 0);
    fill(rs+1, rs+n+1, 0);
    stack<int> stk;
    for (int i = 1; i <= n; i++) {
        int last = 0;
        while (!stk.empty() && a[stk.top()] >= a[i]) {
            last = stk.top();
            stk.pop();
        }
        if (!stk.empty()) rs[stk.top()] = i;
        else rt = i;
        ls[i] = last;
        stk.push(i);
    }
    ans = 1;
    dfs(rt, 1, n);
}

int main() {
    init();
    scanf("%d", &T);
    for (int cas = 1; cas <= T; cas++) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", a+i);
        cal();
        printf("Case #%d: %lld\n", cas, ans);
    }
    return 0;
}
posted @ 2026-09-04 10:38  quanjun  阅读(10)  评论(0)    收藏  举报