题目链接
题意:
一个m张牌,翻转n次,每次翻转xi张牌。求最后的状态数。
最后的正面牌的奇偶性=sigma(xi)
维护好正面数量最小值L,最大值R,最后正面数的范围是L,L+2,….,R。
最后在m张牌中取L,L+2,….,R张 的组合数
费马小定理
a^(p-1) ≡ 1 (mod) p
即
a^(p-2)≡ 1/a (mod) p
计算
C(k,m)=m!/(k! * (m-k)!)=m! * (k! * (m-k)! )^(p-2) (mod p);
#include<bits/stdc++.h>
using namespace std;
const int eps=1e-8;
const int maxn=22;
#define LL __int64
const LL mod=1000000009;
LL f[101000];
int main()
{
int n,m,a;
f[0]=1;
for(int i=1;i<=100000;i++)
f[i]=(f[i-1]*i)%mod;
while(cin>>n>>m)
{
int l=0,r=0,ll,rr;
for(int i=0;i<n;i++)
{
scanf("%d",&a);
//min
if(l>=a) ll=l-a;
else if(r>=a)
{
if(a%2==l%2) ll=0;
else ll=1;
}
else ll=a-r;
//max
if(r+a<=m) rr=r+a;
else if(l+a<=m)
{
if(m%2==(l+a)%2) rr=m;
else rr=m-1;
}
else rr=2*m-a-l;
l=ll,r=rr;
}
LL ans=0;
for(int i=l;i<=r;i+=2)
{
LL t=f[i]*f[m-i]%mod,sum=1;
for(LL j=mod-2;j;j=j>>1,t=(t*t)%mod)
if(j&1) sum=(sum*t)%mod;
ans=(ans+(f[m]*sum)%mod)%mod;
}
cout<<ans<<endl;
}
return 0;
}