[FJOI2016]建筑师
题目描述
小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 n 个建筑,每个建筑的高度是 1 到 n 之间的一个整数。
小 Z 有很严重的强迫症,他不喜欢有两个建筑的高度相同。另外小 Z 觉得如果从最左边(所有建筑都在右边)看能看到 A个建筑,从最右边(所有建筑都在左边)看能看到 B 个建筑,这样的建筑群有着独特的美感。现在,小 Z 想知道满足上述所有条件的建筑方案有多少种?
如果建筑 i的左(右)边没有任何建造比它高,则建筑 i可以从左(右)边看到。两种方案不同,当且仅当存在某个建筑在两种方案下的高度不同。
题解
这个人可以从左边看到A栋楼,从右边看到B栋楼,其实是可以看到A+B-1栋楼,是一个单峰的,中间最高的肯定是高度为n的。
那么我们刨掉n的不管,其实是把这个序列分成了A+B-2个集合,每个集合必须且只能出一个代表元素作为能看到的那个,剩下的随便排。
那就是对于有k个元素的集合来说方案数是(k-1)!正好是k个元素的圆排列。
所以最后的方案就是S(n-1,A+B-2),然后我们还要从A+B-2中选A-1个放左边,其余放右边,所以再乘上个C(A+B-2,A-1)。
代码
#include<iostream>
#include<cstdio>
#define N 50009
#define M 209
using namespace std;
typedef long long ll;
const int mod=1e9+;
const int maxn=;
const int maxm=;
ll c[N][M],s[N][M];
int T,n,A,B;
inline ll rd(){
ll x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
int main(){
T=rd();
s[][]=;
for(int i=;i<=maxn;++i){
for(int j=;j<=min(i,maxm);++j)s[i][j]=(s[i-][j-]+s[i-][j]*(i-)%mod)%mod;
}
for(int i=;i<=maxn;++i){
c[i][]=;
for(int j=;j<=min(i,maxm);++j)c[i][j]=(c[i-][j]+c[i-][j-])%mod;
}
while(T--){
n=rd();A=rd();B=rd();
printf("%lld\n",c[A+B-][A-]*s[n-][A+B-]%mod);
}
return ;
}
[FJOI2016]建筑师的更多相关文章
- 【LG4609】[FJOI2016]建筑师
[LG4609][FJOI2016]建筑师 题面 洛谷 题解 (图片来源于网络) 我们将每个柱子和他右边的省略号看作一个集合 则图中共有\(a+b-2\)个集合 而原来的元素中有\(n-1\)个(除去 ...
- [洛谷P4609] [FJOI2016]建筑师
洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...
- Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues
考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...
- Luogu4609 FJOI2016 建筑师 第一类斯特林数
题目传送门 题意:给出$N$个高度从$1$到$N$的建筑,问有多少种从左往右摆放这些建筑的方法,使得从左往右看能看到$A$个建筑,从右往左看能看到$B$个建筑.$N \leq 5 \times 10^ ...
- Luogu4609 FJOI2016建筑师(斯特林数)
显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...
- P4609 [FJOI2016]建筑师
思路 裸的第一类斯特林数,思路和CF960G相同 预处理组合数和第一类斯特林数回答即可 代码 #include <cstdio> #include <cstring> #inc ...
- 洛谷 P4609: [FJOI2016] 建筑师
本省省选题是需要做的. 题目传送门:洛谷P4609. 题意简述: 求有多少个 \(1\) 到 \(N\) 的排列,满足比之前的所有数都大的数正好有 \(A\) 个,比之后的所有数都大的数正好有 \(B ...
- [Luogu4609][FJOI2016]建筑师
luogu description 一个\(1...n\)的排列,其前缀最大值有\(A\)个,后缀最大值有\(B\)个,求满足要求的排列数. 一个位置\(i\)满足前缀最大当且仅当不存在\(j< ...
- [FJOI2016]建筑师 斯特林数
早期作品,不喜轻喷. LG传送门 组合数与斯特林数的基本应用. 组合数 大家应该都熟悉它的表达式,但我们这里使用它的递推式会更加方便,下面推导组合数的递推式.设\(\binom{n}{m}\)表示在\ ...
随机推荐
- windows10 企业版完整激活
windows10 企业版完整激活 cmd管理员运行 1. 以管理员身份执行cmd命令,然后输入以下命令: slmgr.vbs /upk 由于Win10正式版允许在命令提示符界面使用"Ct ...
- ionic3 导航的应用(页面跳转与参数传递)
about.html(跳转页面) <ion-content padding> <ion-list> <ion-item *ngFor="let he of co ...
- java之日志管理
一. 为什么要使用日志 二. 常见日志框架介绍 三. Logback+SLF4J实战 四. 项目源码下载 五. 参考文章 一. 为什么要使用日志 1. 对IT安全至关重要 当您使用强大的日志管 ...
- Java操作Excel(使用POI)
背景说明 以前写过使用 JXL 操作Excel的例子,但JXL对于Excel 2007版本以后的文件(即扩展名为 .xlsx)无法读取,也找不到可以支持的包.所以,有时不得不用 POI 来操作Exce ...
- C#基础知识之反射
http://blog.csdn.net/educast/article/details/2894892 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理 ...
- Spark RDD持久化、广播变量和累加器
Spark RDD持久化 RDD持久化工作原理 Spark非常重要的一个功能特性就是可以将RDD持久化在内存中.当对RDD执行持久化操作时,每个节点都会将自己操作的RDD的partition持久化到内 ...
- Spark-RDD之Partition源码分析
概要 Spark RDD主要由Dependency.Partition.Partitioner组成,Partition是其中之一.一份待处理的原始数据会被按照相应的逻辑(例如jdbc和hdfs的spl ...
- 【入门】Spring-Boot项目配置Mysql数据库
前言 前面参照SpringBoot官网,自动生成了简单项目点击打开链接 配置数据库和代码遇到的问题 问题1:cannot load driver class :com.mysql.jdbc.Drive ...
- c# 日期函数DateTime.ToString()日期的各种格式
//c# datetime 格式化 DateTime dt = DateTime.Now; //2017/11/14 10:46:56 label1.Text = dt.ToString();//20 ...
- android 实现点击edittext的“小眼睛”切换明密文
android 实现点击edittext的“小眼睛”切换明密文 版权声明:本文为博主原创文章,未经博主允许不得转载. 很多时候,我们为了用户的隐私安全,需要在密码输入的时候,显示密文.为了更 ...