洛谷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;
}
浙公网安备 33010602011771号