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

(图片来源于网络,侵删)
以最高的柱子$n$为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子,我们可以把剩下的$n-1$根柱子放入这$A+B-2$(左边$A-1$个右边$B-1$个)个圆排列中(第一类斯特林数),然后在根据组合数进行区分,有:
$$
ans=s_{n-1}^{A+B-2}\times C_{A+B-2}^{A-1}
$$
预处理第一类斯特林和组合数即可。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using std::min; using std::max;
using std::swap; using std::sort;
typedef long long ll;
template<typename T>
void read(T &x) {
int flag = 1; x = 0; char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
}
const int N = 5e4 + 10, M = 2e2 + 10;
const int P = 1e9 + 7;
int t, n, a, b;
int C[M][M], s[N][M];
int main () {
read(t);
for(int i = 0; i < M; ++i) {
C[i][i] = C[i][0] = 1;
for(int j = 1; j < i; ++j)
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % P;
}
for(int i = 0; i < N; ++i) {
if(i < M) s[i][i] = 1;
for(int j = 1; j < i && j < M; ++j)
s[i][j] = (1ll * s[i - 1][j] * (i - 1) % P + 1ll * s[i - 1][j - 1]) % P;
}
while(t--) {
read(n), read(a), read(b);
if(a + b > n + 1) { puts("0"); continue; }
printf("%lld\n", 1ll * s[n - 1][a + b - 2] * C[a + b - 2][a - 1] % P);
}
return 0;
}
洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)的更多相关文章
- LUOGU P4609 [FJOI2016]建筑师(第一类斯特林数)
传送门 解题思路 好神仙的思路,首先一种排列中按照最高点将左右分开,那么就是要在左边选出\(a-1\)个,右边选出\(b-1\)一个,这个如何计算呢?考虑第一类斯特林数,第一类斯特林数是将\(n\)个 ...
- 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】
题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...
- [洛谷P4609] [FJOI2016]建筑师
洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...
- 洛谷 P4609: [FJOI2016] 建筑师
本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...
- Luogu4609 FJOI2016 建筑师 第一类斯特林数
题目传送门 题意:给出$N$个高度从$1$到$N$的建筑,问有多少种从左往右摆放这些建筑的方法,使得从左往右看能看到$A$个建筑,从右往左看能看到$B$个建筑.$N \leq 5 \times 10^ ...
- Luogu4609 FJOI2016建筑师(斯特林数)
显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...
- [洛谷4609] [FJOI2016]建筑师
题目描述 LOJ题面:https://loj.ac/problem/2173. 洛谷题面:https://www.luogu.org/problemnew/show/P4609. Solution [ ...
- P4609 [FJOI2016]建筑师(第一类斯特林数)
传送门 没想到连黑题都会有双倍经验的 其实这题本质上是和CF960G Bandit Blues一样的,不过那里是要用分治FFT预处理第一类斯特林数,这里直接打表预处理第一类斯特林数就可以了 //min ...
- 【Luogu4609】建筑师(第一类斯特林数,组合数学)
[Luogu4609]建筑师(组合数学) 题面 洛谷 题解 首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑. 考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\ ...
随机推荐
- 51Nod 1049最大子段和 | 模板
Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 1.最大子段和模板 #include "bits/stdc++.h" using namespace ...
- 51Nod 1001数组中和等于K的数对
Input示例 8 9 -1 6 5 3 4 2 9 0 8 Output示例 -1 9 0 8 2 6 3 5 first try: #include "bits/stdc++.h&quo ...
- [洛谷P3763] [TJOI2017]DNA
洛谷题目链接:[TJOI2017]DNA 题目描述 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列S,任意修改其 ...
- 希尔排序Shell sort
希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第一块希尔排序介绍 准备待排数组[6 2 4 1 ...
- Python遍历文件夹和读写文件的方法
需 求 分 析 1.读取指定目录下的所有文件2.读取指定文件,输出文件内容3.创建一个文件并保存到指定目录 实 现 过 程 Python写代码简洁高效,实现以上功能仅用了40行左右的代码~ 昨天用Ja ...
- leaflet一个前端gis框架,比openlayer更简单
leaflet一个前端gis框架,比openlayer更简单 作者github:https://github.com/mourner?tab=overview&from=2009-12-01& ...
- 【NOIP】提高组2015 神奇的幻方
[算法]模拟 #include<cstdio> ; int n,a[maxn][maxn]; int main() { scanf("%d",&n); ,y=n ...
- 用 Docker 来构建 Jumpserver
说明: 项目从 [ Jumpserver 官方 ] fork 而来. 主要更新: OS: ubuntu:18.04 优化了 Dockerfile Jumpserver 版本: 1.4.0 redis ...
- Computer(HDU2196+树形dp+树的直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...
- bzoj 1034 贪心
首先如果我们想取得分最高的话,肯定尽量赢,实在赢不了的话就耗掉对方最高的,那么就有了贪心策略,先排序,我方最弱的马和敌方最弱的相比,高的话赢掉,否则耗掉敌方最高的马. 对于一场比赛,总分是一定的,所以 ...