题目描述

小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数。

小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同。另外小 Z 觉得如果从最左边(所有建筑都在右边)看能看到 A 个建筑,从最右边(所有建筑都在左边)看能看到 B 个建筑,这样的建筑群有着独特的美感。现在,小 Z 想知道满足上述所有条件的建筑方案有多少种?

如果建筑 i 的左(右)边没有任何建造比它高,则建筑 i 可以从左(右)边看到。两种方案不同,当且仅当存在某个建筑在两种方案下的高度不同。

输入格式

第一行一个整数 T,代表 T 组数据。 接下来 T 行,每行三个整数 n,A,B。

输出格式

对于每组数据输出一行答案 mod 1e9+7。

输入输出样例

输入 #1

2
3 2 2
3 1 2

输出 #1

2
1

说明/提示

对于 100% 的数据 :1≤n≤50000, 1≤A,B≤100, 1≤T≤2000001。

​ 这也出到我考试题里了,看到后一脸懵,题都没看懂(因为是简化题面),爆0了(我吐了)

​ 这道题正解是组合数\(+\)第一类斯特林数。

​ 我们如果要有A个前缀最大值,B个后缀最大值,我们可以把\(n\)个数分为\(A + B - 1\)段:高度为\(n\)的为一段,其余的是一个高的挡住一群矮的为一段,大概是这样的:

​ 那么问题可以转化为:将\(n - 1\)个数分为\(A + B - 2\)段,并且每一段不能为空,这不就是第一类斯特林数吗?

​ 最后再考虑每一段在最高的那段左边还是右边就好了,最高的那段左边应该有\(A - 1\)段,右边应该有\(B - 1\)段,所以再乘上个\(C_{A +B - 2} ^ {A - 1}\)就好了。

#include <iostream>
#include <cstdio>
#include <cctype> using namespace std; inline long long read() {
long long s = 0, f = 1; char ch;
while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
return s * f;
} const int N = 3005, M = 3005, mod = 998244353;
int n, a, b;
int jc[N], inv[N], c[M][M], s[N][M]; void make_C() {
jc[0] = jc[1] = inv[0] = inv[1] = 1;
for(int i = 2;i <= M - 5; i++) jc[i] = 1ll * jc[i - 1] * i % mod;
for(int i = 2;i <= M - 5; i++) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
for(int i = 2;i <= M - 5; i++) inv[i] = 1ll * inv[i - 1] * inv[i] % mod;
for(int i = 0;i <= M - 5; i++) c[i][0] = 1;
for(int i = 1;i <= M - 5; i++) {
for(int j = 1;j <= M - 5; j++) {
if(i >= j) c[i][j] = 1ll * jc[i] * inv[j] % mod * inv[i - j] % mod;
}
}
s[0][0] = s[1][1] = 1;
for(int i = 2;i <= N - 5; i++) s[i][1] = 1ll * s[i - 1][1] * (i - 1) % mod;
for(int i = 2;i <= N - 5; i++) {
for(int j = 2;j <= M - 5; j++) {
if(i >= j) s[i][j] = (s[i - 1][j - 1] + 1ll * s[i - 1][j] * (i - 1) % mod) % mod;
}
}
} void init() {
scanf("%d %d %d", &n, &a, &b);
} void work() {
printf("%lld\n", 1ll * s[n - 1][a + b - 2] * c[a + b - 2][a - 1] % mod);
} int main() { // freopen("onesentence.in","r",stdin); freopen("onesentence.out","w",stdout); make_C();
init(); work(); // fclose(stdin); fclose(stdout);
return 0;
}

P4609 建筑师的更多相关文章

  1. Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues

    考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...

  2. 洛谷 P4609: [FJOI2016] 建筑师

    本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...

  3. 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】

    题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...

  4. [洛谷P4609] [FJOI2016]建筑师

    洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...

  5. P4609 [FJOI2016]建筑师

    思路 裸的第一类斯特林数,思路和CF960G相同 预处理组合数和第一类斯特林数回答即可 代码 #include <cstdio> #include <cstring> #inc ...

  6. 洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)

    题面 洛谷 题解 (图片来源于网络,侵删) 以最高的柱子\(n\)为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子 ...

  7. P4609 [FJOI2016]建筑师(第一类斯特林数)

    传送门 没想到连黑题都会有双倍经验的 其实这题本质上是和CF960G Bandit Blues一样的,不过那里是要用分治FFT预处理第一类斯特林数,这里直接打表预处理第一类斯特林数就可以了 //min ...

  8. LUOGU P4609 [FJOI2016]建筑师(第一类斯特林数)

    传送门 解题思路 好神仙的思路,首先一种排列中按照最高点将左右分开,那么就是要在左边选出\(a-1\)个,右边选出\(b-1\)一个,这个如何计算呢?考虑第一类斯特林数,第一类斯特林数是将\(n\)个 ...

  9. [FJOI2016]建筑师

    题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数. 小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同. ...

随机推荐

  1. PV与UV你的网站也可以

    个人博客网站分析 阅读前面的文章,有助于理解本文. 1.是时候来一个个人博客网站了 2.什么?你还没有自己的域名? 3.你的个人博客网站该上线了! 为什么需要流量分析? 各位小伙伴,请看下图,你们发现 ...

  2. day2. 六大基本数据类型简介

    一.基本数据类型 Number 数字类型 (int float bool complex) str 字符串类型 list 列表类型 tuple 元组类型 set 集合类型 dict 字典类型 二.Nu ...

  3. python爬虫学习05-爬取图片

    python爬虫学习05-爬取图片 确定要爬取的网址:https://shenan.tuchong.com/20903415/#image309854686 要爬取的内容:使用浏览器插件xpath对图 ...

  4. adb如何连接Mac版腾讯手游助手

    Mac版腾讯手游助手,的端口是6555: 所以使用adb connect 127.0.0.1:6555 进行连接

  5. Springboot 在@Configuration注解的勒种 使用@Autowired或者@value注解 读取.yml属性失败

    springboot中@value注解,读取yml属性失败 问题场景: 配置ShrioConfig时,想注入.yml的参数进行配置 解决办法: 如果注释掉shiroEhcacheManager 以下所 ...

  6. Java集合最全解析,学集合,看这篇就够用了!!!

    在看集合类之前, 我们要先明白一下概念: 1.数据结构 (1):线性表 [1]:顺序存储结构(也叫顺序表) 一个线性表是n个具有相同特性的数据元素的有限序列.数据元素是一个抽象的符号,其具体含义在不同 ...

  7. 【Linux】linux history命令执行后显示历史命令执行时间

    vim  ~/.bashrc 或者 ~/.bash_profile  或者 获取root权限修改vim /etc/profile 最后添加 export HISTTIMEFORMAT="%F ...

  8. C#LeetCode刷题之#225-用队列实现栈(Implement Stack using Queues)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4106 访问. 使用队列实现栈的下列操作: push(x) -- ...

  9. hdfs学习(二)

    一.HDFS文件限额配置 在多人共用HDFS的环境下,配置设置非常重要.特别是在Hadoop处理大量资料的环境,如果没有配额管理,很容易把所有的空间用完造成别人无法存取.Hdfs的配额设定是针对目录而 ...

  10. vue安装和卸载

    安装最新版本 npm install -g @vue/cli或 yarn global add @vue/cli 卸载之前版本npm uninstall vue-cli -g 或 yarn globa ...