经过n次翻牌以后,我们能得到在m张牌中最少有多少张1,和最多有几张1。然后翻牌数之和的奇偶性和1的张数的奇偶性一致。然后我们就对1的张数最少到最多求和。。就是答案了。。。中间要用到逆元。。因为算组合数不能打表(空间不够)。。也不能一层一层推(时间不够)。。。只能用扩展欧几里得来求了。。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 100005
#define eps 1e-10
#define mod 1000000009
#define INF 99999999
#define lowbit(x) (x&(-x))
//#define lson o<<1, L, mid
//#define rson o<<1 | 1, mid+1, R
typedef long long LL;
//typedef int LL;
using namespace std;
LL n, m;
void extend_gcd(LL a, LL b, LL &d, LL &x, LL &y)
{
if(b == 0) { d = a, x = 1, y = 0; }
else { extend_gcd(b, a%b, d, y, x), y -= x*(a/b); }
}
LL c[maxn];
int main(void)
{
LL a, b, aa, bb, i, x;
LL g, y, ans;
while(scanf("%I64d%I64d", &n, &m)!=EOF) {
a = b = 0;
for(i = 0; i < n; i++) {
scanf("%I64d", &x);
if(a >= x) aa = a-x;
else if(b <= x) aa = x-b;
else {
if((a%2 && x%2) || (a%2 == 0 && x%2 == 0)) aa = 0;
else aa = 1;
}
if(b+x <= m) bb = b+x;
else if(a+x >= m) bb = m+m-a-x;
else {
if((((a+x)%2) && m%2) || (((a+x)%2 == 0) && m%2 == 0)) bb = m;
else bb = m-1;
}
a = aa, b = bb;
}
c[0] = 1, ans = 0;
for(i = 1; i <= m; i++) {
extend_gcd(i, mod, g, x, y);
x=(x%mod+mod)%mod;
c[i] = c[i-1]*(m-i+1)%mod*x%mod;
}
for(i = a; i <= b; i+=2) {
ans += c[i];
ans %=mod;
}
printf("%I64d\n", ans);
}
return 0;
}