Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)
常规题,简单写写罢(((
首先 \(1\) 的位置是什么不重要,我们不妨钦定 \(1\) 号选手最初就处在 \(1\) 号位置,最后答案乘个 \(2^n\) 即可。
显然与 \(1\) 进行比赛的选手一定是区间 \([2,2],[3,4],[5,8],\cdots,[2^{k-1}+1,2^k],\cdots,[2^{n-1}+1,2^n]\) 中的最小值,而由于我们希望 \(1\) 号选手在比赛中取得胜利,故 \([2,2],[3,4],[5,8],\cdots,[2^{k-1}+1,2^k],\cdots,[2^{n-1}+1,2^n]\) 的最小值中不能出现打得过 \(1\) 的选手,于是问题转化为,有多少个 \(2\sim 2^n\) 的排列,使得任意 \(a_i\) 都不是 \([2,2],[3,4],[5,8],\cdots,[2^{k-1}+1,2^k],\cdots,[2^{n-1}+1,2^n]\)。
直接计算不是太容易,考虑容斥,记 \(F(i)\) 为钦定 \(i\) 个 \(a_j\) 是 \([2,2],[3,4],[5,8],\cdots,[2^{k-1}+1,2^k],\cdots,[2^{n-1}+1,2^n]\) 的最小值,剩余随便填的方案数,根据二项式反演,\(ans=\sum\limits_{i=0}^mF(i)(-1)^i\)。
那么怎么求 \(F(i)\) 呢?考虑状压 dp,\(dp_{i,j}\) 表示考虑了 \(a_1\sim a_i\),\(j\) 是一个二进制数,\(j\) 的 \(2^k\) 位为 \(1\) 当且仅当长度为 \(2^k\) 的区间的最小值已经被钦定为 \(a_1\sim a_i\) 中的某个值。考虑转移,显然可以枚举 \(a_{i+1}\) 是否被选择来转移,但是由于你不知道 \((a_i,a_{i+1})\) 中有多少个数已经被填了,故无法计算方案数,因此这个状态设计是不可行的。考虑换个角度,我们反着 \(dp\),\(dp_{i,j}\) 表示考虑了 \(a_{m-i+1}\sim a_m\),这样转移时候,所有被填入 \(j\) 中的区间的数都是 \(\ge a_{m-i+1}\) 的数,转移就容易了许多。枚举 \(a_{m-i}\) 填入了长度为多少的区间,假设为长度为 \(2^k\) 的区间,那么相当于在 \((a_{m-i},2^n]\) 中未填入钦定的区间中的 \(2^n-a_{m-i}-j\) 个数中选择 \(2^k-1\) 个数并排列好,方案数为 \(\dbinom{2^n-a_{m-i}-j}{2^k-1}\times (2^k)!\),预处理组合数转移即可,时间复杂度 \(n^22^n\)。
const int MAXN=16;
const int MAXP=1<<16;
const int MOD=1e9+7;
int n,m,lim,a[MAXN+3],fac[MAXP+5],ifac[MAXP+5];
int dp[MAXN+3][MAXP+5];
void initfac(int n){
fac[0]=ifac[0]=ifac[1]=1;
for(int i=2;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
}
int binom(int x,int y){
if(x<y||x<0||y<0) return 0;
return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;
}
int main(){
scanf("%d%d",&n,&m);lim=1<<n;initfac(lim);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
reverse(a+1,a+m+1);dp[0][0]=1;
for(int i=0;i<m;i++) for(int j=0;j<lim;j++){
for(int k=0;k<n;k++) if(~j>>k&1){
dp[i+1][j|(1<<k)]=(dp[i+1][j|(1<<k)]+1ll*dp[i][j]*binom(lim-a[i+1]-j,(1<<k)-1)%MOD*fac[1<<k])%MOD;
} dp[i+1][j]=(dp[i+1][j]+dp[i][j])%MOD;
}
int ans=0;
for(int i=0;i<lim;i++){
int cnt=__builtin_popcount(i),ways=1ll*dp[m][i]*fac[lim-1-i]%MOD;
if(cnt&1) ans=(ans-ways+MOD)%MOD;else ans=(ans+ways)%MOD;
} printf("%d\n",1ll*ans*lim%MOD);
return 0;
}
Atcoder Regular Contest 093 D - Dark Horse(组合数学+状压 dp)的更多相关文章
- AtCoder Regular Contest 093
AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...
- AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)
Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成 ...
- AtCoder Regular Contest 075 E - Meaningful Mean(树状数组)
题目大意:求一个数组中,平均值不小于k的连续子序列个数 所有数减去k,算个前缀和出来,就变成二维数点问题了. 没有修改,离线的话就是CZL所说的“NOIP最喜欢的套路”了:倒着加进BIT,以权值为数组 ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 094
AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...
- AtCoder Regular Contest 095
AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
随机推荐
- python jinja2初见
吸取了长城杯的教训,学习python-web迫在眉睫. 正常难度的python_template_injection,由于现在没学面向对象,理解原理比较困难,所以先使用简单版复现:并附上正常版的常用p ...
- C/C++编程笔记:浪漫流星雨表白装b程序
作为一个未来可能会成为一个专业程序员的小伙们,不知道你们现在学到哪里了,学了点东西之后有没有想在你女朋友面前装个大大的b呢,今天小编就给你一个机会来研究一下下边的代码吧,保证大写的N,当然大佬是排除在 ...
- 六步教你如何用PADS进行PCB设计?
在使用PADS进行PCB设计的过程中,需要对印制板的设计流程以及相关的注意事项进行重点关注,这样才能更好的为工作组中的设计人员提供系统的设计规范,同时也方便设计人员之间进行相互的交流和检查. 02 设 ...
- reactnative实现qq聊天消息气泡拖拽消失效果
前言(可跳过) 我在开发自己的APP时遇到了一个类似于qq聊天消息气泡拖拽消息的需求,因为在网上没有找到相关的组件,所以自己动手实现了一下 需求:对聊天消息气泡拖拽到一定长度松开时该气泡会消失(可自行 ...
- 『学了就忘』Linux基础 — 13、Linux系统的分区和格式化
目录 1.Linux系统的分区 (1)磁盘分区定义 (2)两种分区表形式 (3)MBR分区类型 2.Linux系统的格式化 (1)格式化定义 (2)格式化说明 1.Linux系统的分区 (1)磁盘分区 ...
- Swift-技巧(一)缩放并填充图片
摘要 直接操作图片来实现它的缩放或者填充多余空间,首选 UIGraphicsBeginImageContext 函数来实现,它就相当于一个画布,你甚至可以用它来涂鸦. 最近有一个需求,就是将图片先等比 ...
- redis的一般使用和常规配置
https://www.cnblogs.com/HTLucky/p/12027889.html Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANS ...
- CSS px的理解
px是像素.然而一个屏幕像素的多少是由屏幕的分辨率决定的. 取个极端的栗子:如果分辨率是1w*1w,你设置一个100px宽的输入框,你只占屏幕的1/100,但是如果屏幕的分辨率是100*100,那么你 ...
- 【Jenkins】jenkins构建python项目提示:'python' 不是内部或外部命令,也不是可运行的程序或批处理文件
一.问题:jenkins构建python项目提示:'python' 不是内部或外部命令,也不是可运行的程序或批处理文件 二.原因:要在jenkins配置本地环境变量 三.解决方案:添加python.e ...
- webpack 之开发环境优化 source-map
webpack 之开发环境优化 source-map /** * source-map:一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误) * [inline ...