[洛谷P4609] [FJOI2016]建筑师
洛谷题目链接:[FJOI2016]建筑师
题目描述
小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一个整数。
小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同。另外小 Z 觉得如果从最左边(所有建筑都在右边)看能看到 \(A\) 个建筑,从最右边(所有建筑都在左边)看能看到 \(B\) 个建筑,这样的建筑群有着独特的美感。现在,小 Z 想知道满足上述所有条件的建筑方案有多少种?
如果建筑 \(i\) 的左(右)边没有任何建造比它高,则建筑 \(i\) 可以从左(右)边看到。两种方案不同,当且仅当存在某个建筑在两种方案下的高度不同。
输入输出格式
输入格式:
第一行一个整数 \(T\),代表 \(T\) 组数据。 接下来 \(T\) 行,每行三个整数 \(n,A,B\)。
输出格式:
对于每组数据输出一行答案 \(\text{mod } 10^9+7\)。
输入输出样例
输入样例#1:
2
3 2 2
3 1 2
输出样例#1:
2
1
说明
对于 \(10 \%\) 的数据 : \(1 \leq n \leq 10\)。
对于 \(20 \%\) 的数据 : \(1 \leq n \leq 100\)。
对于 \(40 \%\) 的数据 : \(1 \leq n \leq 50000, \ 1 \leq T \leq 5\)。
对于 \(100 \%\) 的数据 :\(1 \leq n \leq 50000, \ 1 \leq A, B \leq 100, \ 1 \leq T \leq 200000\)。
题解:
首先来介绍一下斯特林数
这里只需要用到第一类斯特林数.
其实第一类斯特林数\(S(n, m)\)所代表的意义就是将\(n\)个数分成\(m\)个圆排列的方案数.我们知道\(S(n, m)=S(n-1, m-1)+(n-1)*S(n-1, m)\)可以这样理解,我们分两种情况讨论方案数,如果新加入一个数:
- 让它单独组成一个环,方案数为\(S(n-1,m-1)\).
- 将它放在之前\(n-1\)个数的左边,方案数为\((n-1)*S(n-1, m)\).
既然了解了斯特林数的含义,那么这里就可以拿来用了.
考虑找到最高的建筑,它一定会将左右两遍分成两个部分,且左边可以看见\(A-1\)个建筑,右边可以看见\(B-1\)个建筑.
那么除去我们挑出来的最高的建筑,还剩下\(n-1\)个建筑,我们需要将这\(n-1\)个建筑分成\(A+B-2\)个建筑群.一个建筑群指的是一栋可以被看见的建筑和在它后面被挡住的建筑.就像下面这张图红色框框内的建筑:
我们知道,建筑群需要让最高的建筑在最边上,这样才能保证这个建筑群内的建筑只有一座被看见,所以,一个建筑群内的排列相当于是一个圆排列(圆排列是经过旋转之后不相同的排列,也就是说圆排列中的任意一个排列都可以通过旋转来让最高的在最边缘).
然后产生了\(A+B-2\)个建筑群之后,我们需要选\(A-1\)个放在最高的建筑的左边,也就是\(C(A+B-2, A-1)\).
所以最后的答案就是\(C(A+B-2, A-1)*S(n-1, A+B-2)\),先预处理一下就可以\(O(1)\)回答了.
记得要开\(long\ long\)
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4+5;
const int NN = 200+5;
const int mod = 1e9+7;
typedef int _int;
#define int long long
int T, n, a, b, C[NN][NN], S[N][NN];
_int main(){
cin >> T, C[0][0] = S[0][0] = 1;
for(int i = 1; i <= 200; i++) C[i][i] = C[i][0] = 1;
for(int i = 1; i <= 200; i++)
for(int j = 1; j <= i; j++) C[i][j] = (C[i-1][j]+C[i-1][j-1])%mod;
for(int i = 1; i <= 50000; i++)
for(int j = 1; j <= 200; j++) S[i][j] = (S[i-1][j-1]+(i-1)*S[i-1][j]%mod)%mod;
while(T--){
cin >> n >> a >> b;
cout << C[a+b-2][a-1]*S[n-1][a+b-2]%mod << endl;
}
return 0;
}
[洛谷P4609] [FJOI2016]建筑师的更多相关文章
- 洛谷 P4609: [FJOI2016] 建筑师
本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...
- 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】
题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...
- 洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)
题面 洛谷 题解 (图片来源于网络,侵删) 以最高的柱子\(n\)为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子 ...
- [洛谷4609] [FJOI2016]建筑师
题目描述 LOJ题面:https://loj.ac/problem/2173. 洛谷题面:https://www.luogu.org/problemnew/show/P4609. Solution [ ...
- Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues
考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...
- 洛谷P4608 [FJOI2016]所有公共子序列问题 【序列自动机 + dp + 高精】
题目链接 洛谷P4608 题解 建个序列自动机后 第一问暴搜 第二问dp + 高精 设\(f[i][j]\)为两个序列自动机分别走到\(i\)和\(j\)节点的方案数,答案就是\(f[0][0]\) ...
- 洛谷P4587 [FJOI2016]神秘数(主席树)
题面 洛谷 题解 考虑暴力,对于询问中的一段区间\([l,r]\),我们先将其中的数升序排序,假设当前可以表示出\([1,k]\)目前处理\(a_i\),假如\(a_i>k+1\),则答案就是\ ...
- P4609 [FJOI2016]建筑师
思路 裸的第一类斯特林数,思路和CF960G相同 预处理组合数和第一类斯特林数回答即可 代码 #include <cstdio> #include <cstring> #inc ...
- P4609 [FJOI2016]建筑师(第一类斯特林数)
传送门 没想到连黑题都会有双倍经验的 其实这题本质上是和CF960G Bandit Blues一样的,不过那里是要用分治FFT预处理第一类斯特林数,这里直接打表预处理第一类斯特林数就可以了 //min ...
随机推荐
- 第二章:Internet地址结构
引言 本章主要介绍了: 如何为Internet中的设备分配IP地址. 有助于理由可扩展性的地址结构分配方式. 特殊用途的地址. 表示IP地址 IPv4地址 长32位,采用点分四组或点分十进制来表示. ...
- C语言之goto浅析
1. 读代码时遇了的疑惑点: static int do_bind(const char *host, int port, int protocol, int *family) { int fd; ...
- 关于双系统下Ubuntu不能访问Windows中某个盘的问题
1.问题描述 在Ubuntu系统下访问Windows系统中磁盘时出现无法访问的情况,具体如下显示: 该问题为磁盘挂载错误,需要进行修复. 2.解决办法 (1)打开终端:如果没有安装ntfs ...
- 爬虫学习之-git拉取远程错误
本文讲的是把git在最新2.9.2,合并pull两个不同的项目,出现的问题如何去解决 如果合并了两个不同的开始提交的仓库,在新的 git 会发现这两个仓库可能不是同一个,为了防止开发者上传错误,于是就 ...
- PHP面向对象之final关键字
最终类 最终类,其实就是一种特殊要求的类:要求该类不允许往下继承下去. 形式: final class 类名{ //类的成员定义...跟一般类的定义一样! } 最终方法 最终方法,就是一个不允许下 ...
- Ubuntu系统下adb devices 不能显示手机设备
1. 查看usb设备,命令:lsusb 结果如下:Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub B ...
- .netMVC Vue axios 获取数据
网页 <link href="~/Content/css/bootstrap-theme.min.css" rel="stylesheet" /> ...
- 当使用listIterator进行迭代时候 list的迭代器可以在创建迭代器对象后 添加数据 但打印的时候不显示添加后的数据。 collection 的iterator迭代器不能添加数据 。list的对象与collection的实例对象都不能在创建迭代器后添加数据 list的迭代器保存的是循环前的数据长度
- bzoj1318[spoj 744] Longest Permutation
题意 给出一个长度为n的,所有元素大小在[1,n]的整数数列,要求选出一个尽量长的区间使得区间内所有元素组成一个1到区间长度k的排列,输出k的最大值 n<=1e5 分析 不会做,好菜啊.jpg ...
- P4623 [COCI2012-2013#6] BUREK
题目描述 给定N个三角形,和M条直线,直线要么平行于X轴,要么平行于Y轴,问这M条直线 分别经过多少个三角形内部 (注意是内部即分开的两个多边形的面积均大于零). 输入输出格式 输入格式: 第一行一个 ...