【题解】CF1536F Omkar and Akmar
结论:无论怎么走后手一定赢。
这应该是这道题中最难想到的。
这里的一定赢是指不用考虑任何策略,都能躺赢(
反证法,假定先手赢了,此时场上有奇数个位置被填了,那么一定存在去掉空格后相邻的两个格子颜色相同,它们之间还能再填至少一个,所以后手必胜。
然后就非常简单了,我们计算最终状态,如果最终状态有 \(k\) 个位置被填了,那么有 \(k!\) 种方案达到这个状态。
\(k\) 一定是偶数,我们枚举 \(k\) ,计算有多少种最终状态。
最终状态去掉空格后一定是形如 \(AB\cdots AB\) 或者 \(BA\cdots BA\) 的长度为 \(k\) 的串,一个 \(AB\) 中最多只能插入一个空格。
由于是环,讨论一下第一个位置是否为空格。
如果第一个位置不是空格,方案数为 \(2\binom{k}{n-k}\) 。
如果第一个位置为空格,方案数为 \(2\binom{k-1}{n-k-1}\) 。
这样我们就得到了答案。
\[Ans=2\sum\limits_{1\le i\le \left\lfloor\frac{n}{2}\right\rfloor}(2i)!\binom{2i}{n-2i}+(2i)!\binom{2i-1}{n-2i-1}
\]
时间复杂度 \(\mathcal{O}(n+\log P)\) 。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define pre(i,a,b) for(int i=a;i>=b;i--)
#define N 1000005
#define P 1000000007
using namespace std;
int n,fac[N],inv[N];
int Pow(int x,int y){
int now=1;
for(;y;y>>=1,x=1LL*x*x%P)if(y&1)now=1LL*now*x%P;
return now;
}
int C(int x,int y){
if(x<0||y<0||x<y)return 0;
return 1LL*fac[x]*inv[y]%P*inv[x-y]%P;
}
// Sharpness V
int main(){
scanf("%d",&n);fac[0]=1;
rep(i,1,n)fac[i]=1LL*i*fac[i-1]%P;
inv[n]=Pow(fac[n],P-2);
pre(i,n-1,0)inv[i]=1LL*inv[i+1]*(i+1)%P;
int ans=0;
rep(i,1,n/2){
int cur=i*2;
ans=(ans+2LL*fac[cur]*(C(cur,n-cur)+C(cur-1,n-cur-1)))%P;
}
printf("%d\n",ans);
return 0;
}