Educational Codeforces Round 160 (Rated for Div. 2) D. Array Collapse(笛卡尔树+DP)

原题链接:D. Array Collapse


题目大意:


给你一个长度为 n n n 的排列 p p p ,排列的定义为 [ 1 , 2 , 3 , . . , n ] [1,2,3,..,n] [1,2,3,..,n] 中每个数都出现 恰好 一次。

你可以做 任意多次 这样的操作:

选出一个任意长度的子数组(数组中连续的一段),保留其最小的元素,并将其他元素从数组中删去。

现在询问你,按上面的方法操作之后,最终可以获得多少个互不相同的数组,答案对 998 998 998 244 244 244 353 353 353 取模后输出。

解题思路:


我们可以发现一个事实:

因为每次都是保留一个最小元素,假设我们想要保留某一个元素在最终数组里,那么我们只能删除它两边比它大的元素。

假设数组为: [ 4 , 3 , 5 , 2 , 1 , 8 , 6 , 7 ] [4,3,5,2,1,8,6,7] [4,3,5,2,1,8,6,7]

3 3 3 只能删除 [ 1 , 3 ] [1,3] [1,3] 区间的元素, 2 2 2 只能删除 [ 1 , 4 ] [1,4] [1,4] 区间的元素,而最小值 1 1 1 可以把区间 [ 1 , 8 ] [1,8] [1,8] 的元素全都删完,这里的删完是指的是除了自己以外的元素。

我们发现,每个点都管辖着一个区间,我们可以联想到 笛卡尔树 。

比如我们按照下标满足二叉搜索树,权值满足小根堆的方式按照上面的数组,所构建出来的笛卡尔树就是:

在这里插入图片描述
一个节点的子树就是他能管辖到的位置。

这样,我们就能对每个节点管辖到的左右子树进行分类讨论了。

  • 对管辖了 [ 1 , n ] [1,n] [1,n] 的根结点 1 1 1 无论如何也不能删去,没有贡献。
  • 一个节点 u u u 而言,如果我们要保留它,显然它的左右子树的方案是独立的,因此保留它的方案数有 a n s l × a n s r ansl \times ansr ansl×ansr 种。
  • 假设不保留它,而且它管辖了 [ 1 , x ] [1,x] [1,x] 的一段区间,说明它是其左边的最小值,比如 3 3 3 。我们左边没有比我们更小的数来删掉节点 u u u 了,因此我们只能被右边比我们小的 2 2 2 删去,右子树会被随之吞并,而左子树是独立的,所以方案数有 a n s l ansl ansl 种。
  • 假设不保留它,而且它管辖了 [ x , n ] [x,n] [x,n] 的一段区间,说明它是其右边的最小值,比如 6 6 6 。我们右边没有比我们更小的数来删掉节点 u u u 了,因此我们只能被左边比我们小 1 1 1 的删去,左子树会被随之吞并,而右子树是独立的,所以方案数有 a n s r ansr ansr 种。
  • 假设不保留它,而且它管辖了 [ x , y ] [x,y] [x,y] 的一段区间,说明它左右都有比他小的值 。我们既可以被左节点删除,又可以被右节点删除,所以方案数有 a n s l + a n s r − 1 ansl+ansr-1 ansl+ansr1 种。(首先左右子树是独立的,我们点 u u u 被左边删了,而右子树有一个全删完的方案,此时我们计算了一个删空点 u u u 整个子树的方案。而我们被右边删了,左子树有一个全删完的方案,此时我们又计算了一次删空点 u u u 的方案,点 u u u 的子树空被计算了两次,所以要减去 1 1 1

我们只需要从 1 1 1 开始,然后跑递归处理每个点作为子树的方案值,回溯过程中 D P DP DP 即可。

时间复杂度: O ( n ) O(n) O(n)

AC代码:

#include <bits/stdc++.h>
using namespace std;using PII = pair<int, int>;
using i64 = long long;template<class Ty>
struct CartesianTree {vector<int> stk;vector<int> L, R;CartesianTree() {}tuple<int, vector<int>, vector<int>> work(const vector<Ty>& A) {L.assign(A.size(), 0), R.assign(A.size(), 0);int n = A.size() - 1;for (int i = 1; i <= n; ++i) {int lst = 0;while (stk.size() && A[stk.back()] > A[i]) {lst = stk.back();stk.pop_back();}if (stk.size()) {R[stk.back()] = i;}if (lst) {L[i] = lst;}stk.emplace_back(i);}return {stk[0], L, R};}
};const int mod = 998244353;void solve() {int n;cin >> n;vector<int> arr(n + 1);for (int i = 1; i <= n; ++i) {cin >> arr[i];}CartesianTree<int> T;auto [root, L, R] = T.work(arr);auto DFS = [&](auto self, int u, int l, int r) -> i64 {i64 ansl = 1, ansr = 1;if (L[u]) ansl = self(self, L[u], l, u - 1);//有左子树就去左子树if (R[u]) ansr = self(self, R[u], u + 1, r);//有右子树就去右子树i64 ans = ansl * ansr % mod;//保留根的答案//删除根的答案if (l == 1 && r == n);//跳过根节点else if (l == 1) {//只能被右边删ans += ansl;} else if (r == n) {//只能被左边删ans += ansr;} else {//左右都能删ans += ansl;ans += ansr;ans -= 1;}return (ans + mod) % mod;};cout << DFS(DFS, root, 1, n) << '\n';
}signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t = 1; cin >> t;while (t--) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/493310.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PROTEL

PROTEL是什么 Protel软件是由Altium公司&#xff08;原为Protel Technology公司&#xff09;开发的一款电子设计自动化&#xff08;EDA&#xff09;软件&#xff0c;主要用于电子电路设计和印制电路板&#xff08;PCB&#xff09;制作。 学习Protel 99 SE的大致过程 原理图文…

芯科科技与Arduino携手推动Matter普及化

双方的合作可助力开发人员在两分钟内将新开发板配置入网 致力于以安全、智能无线连接技术&#xff0c;建立更互联世界的全球领导厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;日前宣布&#xff0c;公司与开源硬件和软件领域的…

【MySQL】表的约束 -- 详解

表中一定要有各种约束&#xff0c;通过约束让我们在未来插入数据库表中的数据是符合预期的。约束本质是通过技术手段倒逼程序员插入正确的数据&#xff0c;反过来站在 MySQL 的角度&#xff0c;凡是插入进来的数据都是符合数据约束的。约束的最终目标&#xff1a;保证数据的完整…

【c语言】字符函数和字符串函数(上)

前言 在编程的过程中&#xff0c;我们经常要处理字符和字符串&#xff0c;为了⽅便操作字符和字符串&#xff0c;C语⾔标准库中提供了⼀系列库函数~ 欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 前言 1. 字符分…

matlab采用不同数值方法求解微分方程

1、内容简介 略 60-可以交流、咨询、答疑 欧拉方法、改进欧拉、RK4、米尔斯坦方法求解微分方程 2、内容说明 略 lc; close all; clear all; % 参数赋值 global a global b global h a 1; b 2; Ni 1000; % 总步数 h 0.001; % 步长Xt1(1:Ni) 0; Xt2(…

【析】装卸一体化车辆路径问题的自适应并行遗传算法

0 引言 国内外有关 &#xff36;&#xff32;&#xff30;&#xff33;&#xff30;&#xff24;的文献较多&#xff0c;求解目标多以最小化车辆行驶距离为主&#xff0c;但现实中可能存在由租赁费用产生的单次派出成本&#xff0c;需要综合考 虑单次派车成本和配送路径成本。…

数据库系统概论(超详解!!!) 第一节 绪论

1.四个基本概念 1.数据&#xff08;Data&#xff09; 数据&#xff08;Data&#xff09;是数据库中存储的基本对象 数据的定义&#xff1a;描述事物的符号记录 数据的种类&#xff1a;数字、文字、图形、图像、音频、视频、学生的档案记录等 数据的含义称为数据的语义&…

设计模式(六)代理模式

相关文章设计模式系列 1.代理模式简介 代理模式介绍 代理模式也叫委托模式&#xff0c;是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多&#xff0c;比如代购、代理上网、打官司等。 定义 为其他对象提供一种代理以控制这个对象的访问。 代理模式…

Java EE改名Jakarta EE,jakarta对程序开发的影响

一、前言 很多Java程序员在使用新版本的Spring6或者springboot3版本的时候&#xff0c;发现了一些叫jakarta的包。我在阅读开源工作流引擎camunda源代码的时候&#xff0c;也发展了大量jakarta的工程包。 比如&#xff1a;camunda的webapps编译工程就提供了2种方式javax和jaka…

精准测试探索

一、背景 什么是精准测试&#xff1f;通常研发提测的需求有代码变更&#xff0c;针对研发的代码变更点以及关联点进行测试&#xff0c;我们称之为精准测试。 很多时候&#xff0c;对变更点、影响范围的评估并不是很准确&#xff0c;偶尔会出现影响范围评估不全或者影响范围评…

《Docker 简易速速上手小册》第5章 Docker Compose 与服务编排(2024 最新版)

文章目录 5.1 理解 Docker Compose5.1.1 重点基础知识5.1.2 重点案例&#xff1a;部署 Flask 应用和 Redis5.1.3 拓展案例 1&#xff1a;多服务协作5.1.4 拓展案例 2&#xff1a;使用自定义网络 5.2 编排多容器应用5.2.1 重点基础知识5.2.2 重点案例&#xff1a;部署 Flask 应用…

【Vuforia+Unity】AR05-实物3D模型识别功能实现(ModelTarget )

不管是什么类型的识别Vuforia的步骤基本都是: 把被识别的物体转成图、立体图、柱形图,3D模型、环境模型,然后模型生成Vuforia数据库-导入Unity-参考模型位置开始摆放数字内容,然后参考模型自动隐藏-发布APP-识别生活中实物-数字内容叠加上去! 对于3D物体的识别,可以是虚…