博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Luogu4609 FJOI2016 建筑师 第一类斯特林数
阅读量:5064 次
发布时间:2019-06-12

本文共 1398 字,大约阅读时间需要 4 分钟。

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


第一次看到第一类$Stirling$数有用emmm

考虑将某种方案中最高的建筑拿出来,将分成的两半中可以看得见的与被它挡住的建筑分成一个部分,如下

绿色的当然是最高的,剩下的两个部分分成了1,2,3三个部分。可以知道我们总共需要$A+B-2$这样的部分,而其中$A-1$个放在左边,$B-2$个放在右边,所以答案中会有一项$C_{A+B-2}^{A-1}$

考虑如何产生这$A+B-2$个部分。可以发现每一个部分的产生就是一个圆桌排列的产生(相当于在圆桌排列上选择高度最高的建筑,将其拉成一条线,而同一圆桌排列得到的建筑的部分是一样的),所以我们需要让$N-1$个建筑产生$A+B-2$个圆桌排列,也就是$S_{N-1}^{A+B-2}$

又因为圆桌排列扯成一个排列的方式只有一种,且划分左右之后,排列方式也只有一种,所以答案就是$$C_{A+B-2}^{A-1} \times S_{N-1}^{A+B-2}$$

预处理$50000 \times 200$的$Stirling$数和$200 \times 200$的组合数就好

注意:$S_0^0=C_{0}^{0} = 1$

1 #include
2 #define ll long long 3 using namespace std; 4 5 const int MOD = 1e9 + 7; 6 ll Stir[50001][201] , yh[201][201]; 7 8 int main(){ 9 yh[0][0] = Stir[0][0] = 1;10 for(int i = 1 ; i <= 200 ; i++){11 yh[i][0] = 1;12 for(int j = 1 ; j <= i ; j++)13 yh[i][j] = (yh[i - 1][j - 1] + yh[i - 1][j]) % MOD;14 }15 for(int i = 1 ; i <= 50000 ; i++)16 for(int j = 1 ; j <= i && j <= 200 ; j++)17 Stir[i][j] = (Stir[i - 1][j - 1] + Stir[i - 1][j] * (i - 1)) % MOD;18 int K;19 for(cin >> K ; K ; K--){20 int a , b , c;21 cin >> a >> b >> c;22 cout << Stir[a - 1][b + c - 2] * yh[b + c - 2][b - 1] % MOD << endl;23 }24 return 0;25 }

 

转载于:https://www.cnblogs.com/Itst/p/9785797.html

你可能感兴趣的文章
第9课 uart
查看>>
Range和xrange的区别
查看>>
STL容器之vector
查看>>
无法向会话状态服务器发出会话状态请求
查看>>
数据中心虚拟化技术
查看>>
01入门
查看>>
复习文件操作
查看>>
SQL Server 使用作业设置定时任务之一(转载)
查看>>
第二阶段冲刺-01
查看>>
BZOJ1045 HAOI2008 糖果传递
查看>>
发送请求时params和data的区别
查看>>
JavaScript 克隆数组
查看>>
eggs
查看>>
一步步学习微软InfoPath2010和SP2010--第七章节--从SP列表和业务数据连接接收数据(4)--外部项目选取器和业务数据连接...
查看>>
如何增强你的SharePoint 团队网站首页
查看>>
FZU 1914 Funny Positive Sequence(线性算法)
查看>>
oracle 报错ORA-12514: TNS:listener does not currently know of service requested in connec
查看>>
基于grunt构建的前端集成开发环境
查看>>
MySQL服务读取参数文件my.cnf的规律研究探索
查看>>
java string(转)
查看>>