【Luogu4609】建筑师(第一类斯特林数,组合数学)
【Luogu4609】建筑师(组合数学)
题面
题解
首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑。
考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\(i\)个数并且能够看到\(j\)个的方案数,强制最大值在最右侧。
每次添加最小的一个数放进来:\(f[i][j]=f[i-1][j-1]+f[i-1][j]*(i-2)\)
如果把它放在最前面,答案加一,也就是\(f[i-1][j-1]\)转移过来,
否则的话,因为最大值强制放在最后面,所以还剩下\(i-2\)个位置,所以就像上面这样转移。
那么,答案就是:
我们枚举最高的位置,然后两边分开考虑,
那么就是:
\]
这样子复杂度是\(O(100*10^5+Tn)\),可以拿到\(40pts\)
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MOD 1000000007
#define MAX 50050
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int f[MAX][101];
int jc[MAX],jv[MAX],inv[MAX];
int C(int n,int m){return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
int main()
{
f[0][0]=jc[0]=jv[0]=inv[0]=inv[1]=1;
for(int i=1;i<=50000;++i)
for(int j=1;j<=100;++j)
f[i][j]=(f[i-1][j-1]+1ll*f[i-1][j]*(i-2))%MOD;
for(int i=1;i<MAX;++i)jc[i]=1ll*jc[i-1]*i%MOD;
for(int i=2;i<MAX;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<MAX;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;
int T=read();
while(T--)
{
int n=read(),A=read(),B=read(),ans=0;
for(int i=1;i<=n;++i)
ans=(ans+1ll*f[i][A]*f[n-i+1][B]%MOD*C(n-1,i-1)%MOD)%MOD;
printf("%d\n",ans);
}
return 0;
}
然而这样不够优秀,我们继续颓柿子。
还是一样的,从左往右看和从右往左看是一样的。
所以还是只需要考虑一半,从最高的位置分成左右来看。
如果恰好只能够看见了A个建筑的话,我们可以把所有可以看到的建筑以及被它遮住的所有建筑分组,那么,我们可以把这个顺序认为是一个环,那么每一个能够被看见的建筑一定是这个环中的所有建筑中最高的那个,换而言之,一个环就能确定一部分建筑的顺序,使得它们恰好能够被看到一个,那么一个环排列就可以确定着一种方法。
因为现在左边恰好看见\(A\)个,右边恰好看见\(B\)个,所以等价于除了最高位置之外,一共还需要\(A+B-2\)个环,而总共有\(n-1\)个建筑可以用来环排列,而左边还需要看见\(A-1\)个建筑,所以等价于还需要选出\(A-1\)个环,因此总方案数就是\(C_{A+B-2}^{A-1}*S_{n}^{A+B-2}\)
其中\(S\)是第一类斯特林数。
#include<cstdio>
#define MOD 1000000007
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,A,B,ans;
int S[50050][202],C[202][202];
int main()
{
S[0][0]=C[0][0]=C[1][0]=1;
for(int i=1;i<=200;C[++i][0]=1)
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<=i&&j<=200;++j)
S[i][j]=(1ll*S[i-1][j]*(i-1)+S[i-1][j-1])%MOD;
int T=read();
while(T--)
{
n=read(),A=read(),B=read();
printf("%lld\n",1ll*S[n-1][A+B-2]*C[A+B-2][A-1]%MOD);
}
return 0;
}
【Luogu4609】建筑师(第一类斯特林数,组合数学)的更多相关文章
- LUOGU P4609 [FJOI2016]建筑师(第一类斯特林数)
传送门 解题思路 好神仙的思路,首先一种排列中按照最高点将左右分开,那么就是要在左边选出\(a-1\)个,右边选出\(b-1\)一个,这个如何计算呢?考虑第一类斯特林数,第一类斯特林数是将\(n\)个 ...
- Luogu4609 FJOI2016 建筑师 第一类斯特林数
题目传送门 题意:给出$N$个高度从$1$到$N$的建筑,问有多少种从左往右摆放这些建筑的方法,使得从左往右看能看到$A$个建筑,从右往左看能看到$B$个建筑.$N \leq 5 \times 10^ ...
- 【组合数学:第一类斯特林数】【HDU3625】Examining the Rooms
Examining the Rooms Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- Luogu4609 FJOI2016建筑师(斯特林数)
显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...
- 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】
题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...
- 洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)
题面 洛谷 题解 (图片来源于网络,侵删) 以最高的柱子\(n\)为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子 ...
- P4609 [FJOI2016]建筑师(第一类斯特林数)
传送门 没想到连黑题都会有双倍经验的 其实这题本质上是和CF960G Bandit Blues一样的,不过那里是要用分治FFT预处理第一类斯特林数,这里直接打表预处理第一类斯特林数就可以了 //min ...
- CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增
传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...
- 【CF960G】Bandit Blues(第一类斯特林数,FFT)
[CF960G]Bandit Blues(第一类斯特林数,FFT) 题面 洛谷 CF 求前缀最大值有\(a\)个,后缀最大值有\(b\)个的长度为\(n\)的排列个数. 题解 完完全全就是[FJOI] ...
随机推荐
- [Lydsy1805月赛]quailty 算法 BZOJ5362
分析: 题目中描述了一个二分图,让我们求最小权最大匹配,实际上其实是求n个点,在n*(n-1)/2中选n条边的权值和最小,形成一个每个点都有出边的体系,也就是基环树,(证明:因为我们需要二分图最大匹配 ...
- 在 R 中估计 GARCH 参数存在的问题
目录 在 R 中估计 GARCH 参数存在的问题 GARCH 模型基础 估计 GARCH 参数 fGarch 参数估计的行为 结论 译后记 在 R 中估计 GARCH 参数存在的问题 本文翻译自< ...
- 20155211 网络对抗 Exp9 Web安全基础实践
20155211 网络对抗 Exp9 Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? 原理:SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语 ...
- 20155229《网络对抗技术》Exp2:后门原理与实践
实验预习 后门: 指绕过安全控制而获取对程序或系统访问权的方法.最主要目的就是方便以后再次秘密进入或者控制系统. 木马与后门的区别: 木马:通过欺骗用户的方法(包含捆绑,利用网页等)让用户不知不觉的安 ...
- 20155318 《网络攻防》 Exp7 网络欺诈防范
20155318 <网络攻防> Exp7 网络欺诈防范 基础问题 通常在什么场景下容易受到DNS spoof攻击 DNS spoof攻击即执行DNS欺骗攻击,通过使用Ettercap来进行 ...
- 20155334 曹翔 Exp3 免杀原理与实践
20155334 曹翔 Exp3 免杀原理与实践 小记:这次实验,困难重重,失败练练,搞得我们是心急如焚,焦头烂额,哭爹喊娘 一.基础问题回答 杀软是如何检测出恶意代码的? 每个杀软都有自己的检测库, ...
- JavaScript快速入门-实战(例子)
1.模拟bootstrap中的模态框 效果图:(点我后,弹出对话框,最下面的内容可以看到,但是有一定的透明度.) 思路分析: 整体分为三层,最底层(点我),中间透明层(实现透明效果),最顶层(最新内容 ...
- Mysql的基本操作(一)增、删、改
创建/增加(create创建,alter字段操作,insert插入) 创建数据库 create database 数据库名称 charset=utf8; # 例: create database te ...
- [转]申瓯 JSY2000-06 程控电话交换机呼叫转移设置
说明:若申瓯程控电话交换机分机有事不在位置上或遇忙分机正忙时为使某些重要来话不丢失,可设置将呼入本机的电话转移至其他分机及公网固定电话或手机.电话交换机使用了本功能不管分机用户在什么地方都能接听到办公 ...
- Ubuntu Google Chrome
Chrome安装 添加下载源 sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.l ...