Codeforces Round 926 F. Sasha and the Wedding Binary Search Tree

F. Sasha and the Wedding Binary Search Tree

1
2

题意

给定一颗二叉搜索树,规定树上的所有点的点权都在范围 [ 1 , C ] [1, C] [1,C] 内,树上的某些节点点权已知,某些节点点权未知,求出合法的二叉搜索树的数量

思路

由于是二叉搜索树,所以左子树的点权小于等于右子树的点权,我们先进行一次先序遍历,得到一个 o r d e r order order 遍历顺序的数组,其中某些段是未知的点权,我们可以通过其左端点和右端点的点权来约束这些未知点的点权

假如这个未知段左边紧邻的第一个已知点权为 L L L,右边紧邻的第一个已知点权为 R R R,那么显然我们这个未知段的点权是 [ L , R ] [L,R] [L,R] 的,假设未知段长度为 l e n len len,问题等价于选出 l e n len len 个数,按照非递减的顺序摆放的方案数,允许重复数字出现。

我们将问题再转化一下,由于是非递减,所以一定有: v a l i ≤ v a l i + 1 val_i \leq val_{i + 1} valivali+1,那么这一段的差分数组一定是大于等于 0 0 0 的一段,并且总和为 R − L R - L RL,要加上最后一个 R R R 的位置,长度变为 l e n + 1 len + 1 len+1,例如: L = 2 , R = 5 , l e n = 3 L = 2, R= 5, len = 3 L=2,R=5,len=3,我们构造这样一个方案: 2 , 3 , 3 , 4 , 5 2, 3 , 3, 4, 5 2,3,3,4,5,差分数组为: 2 , 1 , 0 , 1 , 1 2, 1, 0, 1, 1 2,1,0,1,1,忽略第一个位置的话,后面所有元素的和就是 R − L = 3 R - L = 3 RL=3,那么问题成功转化为了:将 R − L R - L RL 个相同小球放入 l e n + 1 len + 1 len+1 个不同盒子中(允许空盒子)的方案数,即为: C R − L + l e n l e n C_{R - L + len}^{len} CRL+lenlen

由于这里 R − L R - L RL 很大,所以不能直接预处理阶乘,注意到 ∑ l e n ≤ n \sum len \leq n lenn,我们只需要利用公式: C R − L + l e n l e n = ( R − L + l e n ) ⋅ ( R − L + l e n − 1 ) ⋅ . . . ⋅ ( R − L + 1 ) l e n ! C_{R - L + len}^{len} = \dfrac{(R - L + len) \cdot (R - L + len - 1) \cdot ... \cdot (R - L + 1)}{len!} CRL+lenlen=len!(RL+len)(RL+len1)...(RL+1) 来计算即可

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;const int INF=0x3f3f3f3f;
const long long INFLL=1e18;typedef long long ll;template<class T>
constexpr T power(T a, ll b){T res = 1;while(b){if(b&1) res = res * a;a = a * a;b >>= 1;}return res;
}constexpr ll mul(ll a,ll b,ll mod){ //快速乘,避免两个long long相乘取模溢出ll res = a * b - ll(1.L * a * b / mod) * mod;res %= mod;if(res < 0) res += mod; //误差return res;
}template<ll P>
struct MLL{ll x;constexpr MLL() = default;constexpr MLL(ll x) : x(norm(x % getMod())) {}static ll Mod;constexpr static ll getMod(){if(P > 0) return P;return Mod;}constexpr static void setMod(int _Mod){Mod = _Mod;}constexpr ll norm(ll x) const{if(x < 0){x += getMod();}if(x >= getMod()){x -= getMod();}return x;}constexpr ll val() const{return x;}explicit constexpr operator ll() const{ return x; //将结构体显示转换为ll类型: ll res = static_cast<ll>(OBJ)}constexpr MLL operator -() const{ //负号,等价于加上ModMLL res;res.x = norm(getMod() - x);return res;}constexpr MLL inv() const{assert(x != 0);return power(*this, getMod() - 2); //用费马小定理求逆}constexpr MLL& operator *= (MLL rhs) & { //& 表示“this”指针不能指向一个临时对象或const对象x = mul(x, rhs.x, getMod()); //该函数只能被一个左值调用return *this;}constexpr MLL& operator += (MLL rhs) & {x = norm(x + rhs.x);return *this;}constexpr MLL& operator -= (MLL rhs) & {x = norm(x - rhs.x);return *this;}constexpr MLL& operator /= (MLL rhs) & {return *this *= rhs.inv();}friend constexpr MLL operator * (MLL lhs, MLL rhs){MLL res = lhs;res *= rhs;return res;}friend constexpr MLL operator + (MLL lhs, MLL rhs){MLL res = lhs;res += rhs;return res;}friend constexpr MLL operator - (MLL lhs, MLL rhs){MLL res = lhs;res -= rhs;return res;}friend constexpr MLL operator / (MLL lhs, MLL rhs){MLL res = lhs;res /= rhs;return res;}friend constexpr std::istream& operator >> (std::istream& is, MLL& a){ll v;is >> v;a = MLL(v);return is;}friend constexpr std::ostream& operator << (std::ostream& os, MLL& a){return os << a.val();}friend constexpr bool operator == (MLL lhs, MLL rhs){return lhs.val() == rhs.val();}friend constexpr bool operator != (MLL lhs, MLL rhs){return lhs.val() != rhs.val();}
};const ll mod = 998244353;
using Z = MLL<mod>;struct Comb {int n;std::vector<Z> _fac;std::vector<Z> _invfac;std::vector<Z> _inv;Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}Comb(int n) : Comb() {init(n);}void init(int m) {m = std::min(1ll * m, Z::getMod() - 1);if (m <= n) return; //已经处理完了需要的长度_fac.resize(m + 1);_invfac.resize(m + 1);_inv.resize(m + 1);for (int i = n + 1; i <= m; i++) {_fac[i] = _fac[i - 1] * i;}_invfac[m] = _fac[m].inv();for (int i = m; i > n; i--) { //线性递推逆元和阶乘逆元_invfac[i - 1] = _invfac[i] * i;_inv[i] = _invfac[i] * _fac[i - 1];}n = m; //新的长度}Z fac(int m) {if (m > n) init(2 * m);return _fac[m];}Z invfac(int m) {if (m > n) init(2 * m);return _invfac[m];}Z inv(int m) {if (m > n) init(2 * m);return _inv[m];}Z binom(int n, int m) { //二项式系数if (n < m || m < 0) return 0;return fac(n) * invfac(m) * invfac(n - m);}
} comb;const int N = 500050;int L[N], R[N];
ll val[N];
std::vector<ll> order;void dfs(int u){if(~L[u]) dfs(L[u]);order.push_back(val[u]);if(~R[u]) dfs(R[u]);
}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int t;std::cin >> t;while(t--){int n;ll C;std::cin >> n >> C;fore(i, 1, n + 1) std::cin >> L[i] >> R[i] >> val[i];order.clear();order.push_back(1);dfs(1);order.push_back(C);Z ans = 1;int idx = 1;while(idx <= n){while(idx <= n && ~order[idx]) ++idx;int l = order[idx - 1];int len = 0;while(idx <= n && order[idx] == -1){++idx;len += 1;}int r = order[idx];Z res = 1;for(int i = r - l + len; i >= r - l + 1; --i) res *= i;res *= comb.invfac(len);ans *= res;}std::cout << ans << endl;}return 0;
}

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

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

相关文章

这应该是全网第一篇全面解读OpenAI Sora报告的文章,精读报告:Video generation models as world simulators

今天是2024年2月16号&#xff0c;大年初七&#xff0c;年还没过完&#xff0c;早晨起来朋友圈就被Sora刷屏了。本来以为没啥&#xff0c;都是公众号或者视屏啥的&#xff0c;都没点开看&#xff0c;直到看到我导也发了Sora的文章&#xff0c;我就知道这个事情不简单了。 先来看…

支付宝沙箱版模拟网站在线完整支付流程(无营业无费用)内网穿透+局域网测试

文章目录 一、介绍1. 支付2. 支付结果 二、前提准备1. 支付宝开放平台2. 内网穿透3. 局域网 三、order微服务1. 依赖、配置2. 工具类1. 二维码生成2. AlipayConfig 3. 端点代码1. /generatepaycode2. /requestpay3. /payresult4. /receivenotify 环境如下 Version手机安卓支付…

红队笔记Day4 -->多层代理(模拟企业拓扑)

声明&#xff1a;本机文章只用于教育用途&#xff0c;无不良引导&#xff0c;禁止用于从事任何违法活动 前几天的红队笔记的网络拓扑都比较简单&#xff0c;今天就来模拟一下企业的真实网络拓扑&#xff0c;以及攻击方法 一般的大企业的网络拓扑如下&#xff1a;&#xff1a;…

基于Springboot+Vue实现的宿舍管理系统

基于SpringbootVue的宿舍管理系统 1.系统相关性介绍1.1 系统架构1.2 设计思路 2.功能模块介绍2.1 用户信息模块2.2 宿舍管理模块2.3 信息管理模块 3. 源码获取以及远程部署 前言&#xff1a; 在现代教育环境中&#xff0c;学生宿舍的管理显得尤为重要&#xff0c;需要一套能…

如何在Windows中配置多个显示器?这里提供详细步骤

Windows可以通过多种方式使用多个显示器&#xff0c;扩展或复制主显示器。你甚至可以关闭主显示器。以下是如何使用简单的键盘快捷键更改辅助显示设置。 使用WindowsP投影菜单 要快速更改Windows 10处理多个显示器的方式&#xff0c;请按WindowsP。屏幕右侧会弹出一个名为“投…

图表示学习 Graph Representation Learning chapter1 引言

图表示学习 Graph Representation Learning chapter1 引言 前言1.1图的定义1.1.1多关系图1.1.2特征信息 1.2机器学习在图中的应用1.2.1 节点分类1.2.2 关系预测1.2.3 聚类和组织检测1.2.4 图分类、回归、聚类 前言 虽然我并不研究图神经网络&#xff0c;但是我认为图高效的表示…

电脑重装系统之Windows 10 企业版 LTSC 2021

简介 Windows 10 22H2对于我来说太不简洁&#xff0c;最受不了的一点是微软强行硬塞给我一些并没有什么luan用的应用和功能&#xff0c;比如&#xff1a;天气&#xff0c;Onedrive......以及臃肿的ui设计。而且强行进行自动更新&#xff0c;我是真的受不了这个&#xff0c;看着…

leetcode:343.整数拆分

解题思路&#xff1a; 拆分的越多越好&#xff08;暂且认为&#xff09;&#xff0c;尽可能拆成m个近似相等的数&#xff0c;会使得乘积最大 dp含义&#xff1a;将i进行拆分得到最大的积为dp[i] 递推公式&#xff1a;j x dp[i-j](固定j&#xff0c;只通过凑dp[i-j]进而实现所…

optee UTA加载

流程 动态TA按照存储位置的不同分为REE filesystem TA&#xff1a;存放在REE侧文件系统里的TA&#xff1b; Early TA&#xff1a;被嵌入到optee os里的在supplicant启动之前就可用了。 这里我们讲的是常规的存放在REE侧文件系统里的TA。 通过GP标准调用的与TA通信的命令(opens…

【AIGC】Stable Diffusion的ControlNet参数入门

Stable Diffusion 中的 ControlNet 是一种用于控制图像生成过程的技术&#xff0c;它可以指导模型生成特定风格、内容或属性的图像。下面是关于 ControlNet 的界面参数的详细解释&#xff1a; 低显存模式 是一种在深度学习任务中用于处理显存受限设备的技术。在这种模式下&am…

Vue的一些基础设置

1.浏览器控制台显示Vue 设置找到扩展&#xff0c;搜索Vue 下载这个 然后 点击扩展按钮 点击详细信息 选择这个&#xff0c;然后重启一下就好了 ——————————————————————————————————————————— 2.优化工程结构 src的components里要…

MySQL数据库基础第四篇(多表查询与事务)

文章目录 一、多表关系二、多表查询三、内连接查询四、外连接查询五、自连接查询六、联合查询 union, union all七、子查询1.标量子查询2.列子查询3.行子查询4.表子查询 八、事务八、事务的四大特性九、并发事务问题十、事务隔离级级别 在这篇文章中&#xff0c;我们将深入探讨…

数据结构之队的实现

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

用HTML5 Canvas创造视觉盛宴——动态彩色线条效果

目录 一、程序代码 二、代码原理 三、运行效果 一、程序代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- 声明文档类型为XHTML 1.0 Transitional -…

Python四级考试笔记

Python四级考试笔记【源源老师】 四级标准 一、 理解函数及过程、函数的参数、函数的返回值、变量作用域等概念。 二、 能够创建简单的自定义函数。 三、 理解算法以及算法性能、效率的概念&#xff0c;初步认识算法优化 效率的方法。 四、 理解基本算法中递归的概念。 五、 掌…

【开源】SpringBoot框架开发独居老人物资配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统&#xff0c;包含了社区档案、…

win7自带截图工具保存失效解决办法

今日发现一台远航技术的win7中自带的截图工具使用时正常&#xff0c;保存图片时没有弹出保存位置的对话窗口&#xff0c;无法正常保存图片。解决方案如下&#xff1a; 1、进入注册表编辑器。开始-搜索程序和文件-输入 regedit 按下回车键&#xff0c;打开注册表&#xff1b; 2、…

多模态基础---BERT

1. BERT简介 BERT用于将一个输入的句子转换为word_embedding&#xff0c;本质上是多个Transformer的Encoder堆叠在一起。 其中单个Transformer Encoder结构如下&#xff1a; BERT-Base采用了12个Transformer Encoder。 BERT-large采用了24个Transformer Encoder。 2. BERT的…

静态时序分析:SDC约束命令set_clock_transition详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在静态时序分析&#xff1a;SDC约束命令create_clock详解一文的最后&#xff0c;我们谈到了针对理想(ideal)时钟&#xff0c;可以使用set_clock_transition命令直…

数据结构与算法:双向链表

朋友们大家好啊&#xff0c;在上节完成单链表的讲解后&#xff0c;我们本篇文章来对带头循环双向链表进行讲解 双向链表 双向链表、头节点和循环的介绍构建双向链表节点的构建初始化双向循环链表&#xff08;空链表&#xff09;销毁双向链表 链表的打印双向链表头尾的插与删尾插…