题解 [ZJOI2010]排列计数
2024-10-21 02:43:03
好题。
% 你赛考到了不会摆烂,后来发现原来有向下取整,题面没有。。。(
就算有我也做不出来啦 qAq
首先我们会发现这个长得就是小根堆,答案就变成了小根堆的计数。
首先最小的数字肯定放在根的位置。我们令 \(f_i\) 为有 \(i\) 个数字组成的小根堆形态数量。显然小根堆左儿子和右儿子的数量是固定的,令左儿子 \(l\) 个右儿子 \(r\) 个,则显然有 \(f_i = C_{i - 1}^l\times f_l \times f_r\)。
组合数用 Lucas 求。
#include <iostream>
#define MAXN 1000000
using namespace std;
int n, m, Mod;
int qpow(int n, int m) {
int res = 1, bas = n;
while(m) {
if(m & 1) res = res * bas % Mod;
bas = bas * bas % Mod;
m >>= 1;
}
return res;
}
int fac[MAXN + 10];
void pre() {
fac[0] = 1, fac[1] = 1;
for(int p = 2; p <= MAXN; p++) fac[p] = fac[p - 1] * p % Mod;
}
int inv(int x) {
return qpow(x, Mod - 2);
}
int C(int n, int m) {//C_n^m
if(m > n) return 0;
return fac[n] * inv(fac[m]) % Mod * inv(fac[n - m]) % Mod;
}
int Lucas(int n, int m) {//C_n^m
if(!m) return 1;
else return Lucas(n / Mod, m / Mod) * C(n % Mod, m % Mod) % Mod;
}
int f[MAXN + 10];
int main() {
cin >> n >> Mod;
pre();
f[1] = 1, f[2] = 1, f[3] = 2;
int l = 1, r = 1, lim = 3;
for(int p = 4; p <= n; p++) {
if(l < lim) l++;
else r++;
if(l == r) lim = (lim + 1) * 2 - 1;
f[p] = Lucas(p - 1, l) * f[l] % Mod * f[r] % Mod;
}
cout << f[n] << endl;
}
最新文章
- ThroughRain第一次冲刺(每天更新)
- linux-14基础命令之-复制(cp)移动(mv),删除(rm),拷贝文件(dd)
- error CS0016: 未能写入输出文件
- [Apache] 2.2与2.4版本在设置虚拟域名时的小差别
- JDBC批量插入数据效率分析
- 在线教育平台搭建 预览和models
- [C++]UVaLive7324 ASCII Addtion
- JS操作数组-2
- webpack2.0 css文件引入错误解决及图片输出在根目录配置问题
- vi命令【方向键】变字母键的解决方法
- VS2015 C#的单元测试
- Datetime 24小时制
- Commons FileUpload文件上传组件
- ArchLinux - 安装指南
- php 的swoole 和websocket 连接wss
- html5游戏开发--";动静";结合(二)-用地图块拼成大地图 &; 初探lufylegend
- Eclipse 调试 NodeJS
- Byzantine failures
- java容器 Map Set List
- 泊松分布 &; 指数分布
热门文章
- SpringBoot基础学习笔记
- 数值计算:前向和反向自动微分(Python实现)
- [数据与分析可视化] D3入门教程1-d3基础知识
- [python] 基于matplotlib实现圆环图的绘制
- LeetCode-02 两数相加(Add Two Numbers)
- [Leetcode]设计链表
- [C++]const_cast,dynamic_cast,reinterpret_cast,static_cast转型
- 【深入浅出Seata原理及实战】「入门基础专题」带你透析认识Seata分布式事务服务的原理和流程(1)
- Python 跨模块使用全局变量(自定义类型)
- 无需依赖Docker环境制作镜像