题意: 我们现在有一个有2的n次方的人的淘汰赛,每次相邻的两个人打,赢得人晋级,以此类推到只剩一个人为止。给定一个集合a[i], 规则如下:1号和a[i]的人打a[i]胜,1号和其他人打 1号胜利,其他号和其他的打,字典序小的胜。问1号胜利的方案数有多少种。
我们先假装第一个人就在第一个位置,由于都是从一个2^1的人中取胜,到从2^n的人中取胜,所以一号人在哪方案数都是一样的,所以我们可以假装第一个人就在第一个位置,最后算答案的时候×2^n即可。
接着我们观察1的对手是谁, 我们假设n=3, 那么 n的对手就是 2 , [3,4] , [5,8] 的胜者,即为1向后推 2^0次方的长度到2^n-1次方的长度每一个区间的胜者,所以这些区间的胜者不能为a[i]。由于都和1无关,所以要求就是这些区间中字典序最小的不能是a[i]。正着做不好做,我们考虑某个区间胜者是a[i]的方案数,最后容斥一下就好了。
令dp[i][state]表示考虑到第i个a[i]了,有那些区间的胜者已经是a[i]了。很显然每个a[i]可以有两种选择,第一种不选,第二种找一个没有选的区间加入到其中,设区间长度为len,就还要找 len-1个比它大的填入到这个区间里。 由于dp的状态的0,1就表示每个区间选了没选,所以state的数值就表示了有多少个人选了。这里注意到要找的是比a[i]大的并不是很好找,所以我们按a[i]从大到小排序,那么这时比a[i]大的数字就是n-state-a[i]个了。
等等这时候不就求出来了吗,要容斥啥??? 因为对于没有选的区间,我们是随便放剩下的,所以可能会把是a[i]的放到某个区间做最小值了。
所以 如果state里有j个1,那么我们求出来的就是 有大于等于j的区间被a[i]放了的方案数,我们就根据j的奇偶性加加减减就好啦,最后记得乘2的n此方。
下附AC代码。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn (1<<17)+5
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
int n,m;
int a[20];
ll fac[maxn],inv[maxn];
ll dp[20][maxn];
ll quickpow(ll p,ll k)
{
ll ans=1;
while(k)
{
if(k&1)
ans=(ans*p)%mod;
p=(p*p)%mod;
k>>=1;
}
return ans;
}
ll c(ll n1,ll m1)
{
if(n1<m1) return 0;
return fac[n1]*inv[m1]%mod*inv[n1-m1]%mod;
}
int getbit(int now)
{
int res=0;
while(now)
res+=(now&1),now>>=1;
return res;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&a[m-i+1]);
fac[0]=1;
for(int i=1;i<=maxn-5;i++)
fac[i]=fac[i-1]*i%mod;
inv[maxn-5]=quickpow(fac[maxn-5],mod-2);
for(int i=maxn-5;i>=1;i--)
inv[i-1]=inv[i]*i%mod;
inv[0]=1;
dp[0][0]=1;
for(int i=0;i<m;i++)
{
for(int state=0;state<(1<<n);state++)
if(dp[i][state])
{
dp[i+1][state]+=dp[i][state];
dp[i+1][state]%=mod;
for(int j=0;j<n;j++)
if(((1<<j)&state)==0)
{
dp[i+1][state|(1<<j)]+=(dp[i][state]*fac[(1<<j)]%mod*c((1<<n)-state-a[i+1],(1<<j)-1)%mod);
dp[i+1][state|(1<<j)]%=mod;
}
}
}
ll ans=0;
for(int state=0;state<(1<<n);state++)
{
int cnt=getbit(state);
ll f=(cnt&1)?-1:1;
ans=(ans+f*dp[m][state]*fac[(1<<n)-state-1])%mod;
}
ans=(ans%mod+mod)%mod;
printf("%lld\n",(ans*(1<<n))%mod);
}
Especially For U
By ZRX