【NOI2022省选挑战赛 Contest10 B】早该砍砍了(笛卡尔树)(DP)

早该砍砍了

题目链接:NOI2022省选挑战赛 Contest10 B

题目大意

给你一个序列,保证任意两个位置的数都不相同,你每次可以选择一个区间把里面的数都变成其中的最小值,问你操作若干次(可以不操作)之后序列的样子有多少种。

思路

考虑求出序列每个位置的“管辖范围”(这是这段范围里面的区间去的最小值都是它),这个不难用笛卡尔树求出。

然后我们因为它说序列每个位置的数都不一样,所以我们考虑 DP。
fi,j 为考虑了前 i 个序列的数的覆盖范围,然后当前最优覆盖到 j 的方案数。
然后你要想到一个数的覆盖区间不一定包括它自己(因为其实可能后面会有更小的把它给覆盖了,但是它还有一些旁边的覆盖的位置没有被覆盖)
然后 DP 即可。

代码

#include<cstdio> #include<iostream> #define ll long long #define mo 1000000007 using namespace std; int n, a[3001]; int minn[3001][15], pla[3001][15], log2_[3001]; ll f[3001][3001]; struct node { int l, r, ls, rs; }t[3001]; int rt; int get_min(int l, int r) { int k = log2_[r - l + 1]; if (minn[l][k] < minn[r - (1 << k) + 1][k]) return pla[l][k]; else return pla[r - (1 << k) + 1][k]; } int build(int l, int r) { if (l == r) { t[l].l = l; t[r].r = r; return l; } int now = get_min(l, r); t[now].l = l; t[now].r = r; if (l != now) t[now].ls = build(l, now - 1); if (now != r) t[now].rs = build(now + 1, r); return now; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]), minn[i][0] = a[i], pla[i][0] = i; for (int i = 1; i <= 14; i++) for (int j = 1; j + (1 << i) - 1 <= n; j++) if (minn[j][i - 1] < minn[j + (1 << (i - 1))][i - 1]) minn[j][i] = minn[j][i - 1], pla[j][i] = pla[j][i - 1]; else minn[j][i] = minn[j + (1 << (i - 1))][i - 1], pla[j][i] = pla[j + (1 << (i - 1))][i - 1]; log2_[0] = -1; for (int i = 1; i <= n; i++) log2_[i] = log2_[i >> 1] + 1; rt = build(1, n); f[0][0] = 1; for (int i = 1; i <= n; i++) { ll sum = 0; for (int j = t[i].l; j <= t[i].r; j++) { sum = (sum + f[i - 1][j - 1]) % mo; f[i][j] = (f[i][j] + sum) % mo; } for (int j = 0; j <= n; j++) f[i][j] = (f[i][j] + f[i - 1][j]) % mo; } printf("%lld", f[n][n]); return 0; }

__EOF__

本文作者あおいSakura
本文链接https://www.cnblogs.com/Sakura-TJH/p/16036243.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   あおいSakura  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示