传送门

首先对于高度为\(n\)的建筑,他的左边有\(A-1\)个建筑能被看到,右边有\(B-1\)个建筑能被看到,这两者类似,所以先来看左边。

一个建筑将会遮挡住它后面的高度比它矮的建筑,直到一个高度比他高的出现,所以我们不妨按这样分段看一下,例如下面这个排列

  1. 3 2 4 1 5 7 6

分段后会变成

  1. [3 2][4 1][5][7 6]

我们要求的就是高度为\(n\)的建筑左边有\(A-1\)段,右边有\(B-1\)段的方案数。

不难想到讲每一段看成一个圆排列,然后讲最大的一个元素作为排列的第一个,然后从左到右形成一段。

例如这个圆排列\((1,5,3)\),将\(5\)提到第一个后会变成\([5,3,1]\),这样就对应了上面说的一段。

那么我们只要把\(1...n-1\)这\(n-1\)个数安排到\(A+B-2\)个圆排列里,然后在\(n\)的左边放\(A-1\)个圆排列,其中这\(A-1\)个 圆排列按排列中的最大数做关键字从小到大放就好了,右边\(B-1\)个排列按从大到小放。

这样答案就是\(s(n-1,A+B-2) \times C(A+B-2,A-1)\)

其中\(C(n,r)\)表示组合数,\(s(n,k)\)表示第一类Stirling数,预处理出第一类斯特林数和组合数,\(O(1)\)的回答就好了

\(Code:\)

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=50010,P=1e9+7;
  4. inline int add(int x,int y){return (x+=y)>=P?x-P:x;}
  5. inline int sub(int x,int y){return (x-=y)<0?x+P:x;}
  6. int s[N][310],C[310][310];
  7. int main()
  8. {
  9. s[0][0]=1;
  10. for(int i=1;i<=50000;i++)
  11. for(int j=1;j<=min(i,200);j++)
  12. s[i][j]=add(1ll*s[i-1][j]*(i-1)%P,s[i-1][j-1]);
  13. C[0][0]=1;
  14. for(int i=1;i<=200;i++)
  15. {
  16. C[i][0]=C[i][i]=1;
  17. for(int j=1;j<i;j++)
  18. C[i][j]=add(C[i-1][j],C[i-1][j-1]);
  19. }
  20. int _;scanf("%d",&_);while(_--)
  21. {
  22. int n,A,B; scanf("%d%d%d",&n,&A,&B);
  23. printf("%d\n",1ll*s[n-1][A+B-2]*C[A+B-2][A-1]%P);
  24. }
  25. return 0;
  26. }

[题解] LuoguP4609 [FJOI2016]建筑师的更多相关文章

  1. 【LG4609】[FJOI2016]建筑师

    [LG4609][FJOI2016]建筑师 题面 洛谷 题解 (图片来源于网络) 我们将每个柱子和他右边的省略号看作一个集合 则图中共有\(a+b-2\)个集合 而原来的元素中有\(n-1\)个(除去 ...

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

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

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

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

  4. [FJOI2016]建筑师

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

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

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

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

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

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

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

  8. Luogu4609 FJOI2016 建筑师 第一类斯特林数

    题目传送门 题意:给出$N$个高度从$1$到$N$的建筑,问有多少种从左往右摆放这些建筑的方法,使得从左往右看能看到$A$个建筑,从右往左看能看到$B$个建筑.$N \leq 5 \times 10^ ...

  9. Luogu4609 FJOI2016建筑师(斯特林数)

    显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...

随机推荐

  1. Kibana7.3.2与ElasticSearch7.3.2的集成

    上接: Ubuntu18.04 ElasticSearch7.3.2集群搭建 上传二进制包解压到指定目录, 修改目录名 tar -xzvf tar xzvf kibana-6.3.2-linux-x8 ...

  2. GoJS组织结构图2

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Golang gin开源实例——接口

    Github地址 https://github.com/EDDYCJY/go-gin-example 返回值 字段:code.msg.data 举例 # 失败 { , "msg": ...

  4. C# 篇基础知识3——面向对象编程

    面向过程的结构化编程,例如1972年美国贝尔研究所推出的C语言,这类编程方式重点放在在定函数上,将较大任务分解成若干小任务,每个小任务由函数实现,分而治之的思想,然而随着软件规模的不断扩张,软件的复杂 ...

  5. Html5使用audio播放音乐

    html代码 <audio  id="myaudio" src="http://ws.stream.qqmusic.qq.com/C100003R74Cn0JR4O ...

  6. 使用FFmpeg处理视频文件:视频转码、剪切、合并、播放速调整

    安装 略. 转码 最简单命令如下: ffmpeg -i out.ogv -vcodec h264 out.mp4ffmpeg -i out.ogv -vcodec mpeg4 out.mp4ffmpe ...

  7. HDU1880 魔咒词典

    题目大意:对应的输入多行,每行两个字符串,两个字符串互相映射.接下来询问的时候,如果这个字符串出现过,输出其对应的字符串. 分析:二重哈希来判断字符串是否存在,输出其对应的字符串就行.二重哈希的入门题 ...

  8. 编程题目 定义栈的数据类型,请在类型中实现一个能够得到栈最小元素的minx函数。

    首先自己用 节点 实现了 栈 这种数据类型 为了实现题目了要求,我使用的两个栈. 一个栈 用来 push pop 用户的数据, 另外一个栈用来存放 最小元素(涉及元素比较) 代码如下: #!/usr/ ...

  9. 【LeetCode】基本计算器II

    [问题]实现一个基本的计算器来计算一个简单的字符串表达式的值.字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  .整数除法仅保留整数部分. 输入: "3+2*2" ...

  10. IO、阻塞和非阻塞、目录

    系统函数.系统调用 系统函数 open/close函数 函数原型 man 2 open // open, creat - open and possibly create a file or devi ...