hdu4869Turn the pokers 组合数学+求逆元

来源:互联网 发布:党员教师知敬畏明底线 编辑:程序博客网 时间:2024/04/28 21:45
//m个卡片 , n次操作 , 每次操作可以将xi张卡片反转//问最后有多少卡片的情况//对于最后卡片的情况 , 1的数目个数的奇偶性肯定和奇数xi的个数的奇偶性一样//因为奇数xi可以将1的个数加上奇数或者减去奇数 //而且这个1的数目区间一定是连续的[st,en]//那么就是维护st 和 en//对于st是有1就翻1//en是有0就翻0#include<cstdio>#include<cstring>#include<iostream>using namespace std ;typedef long long ll ;const ll mod = 1000000009 ;const int maxn =1e5+10 ;ll c[maxn] ;ll  exgcd(ll a , ll b , ll &x , ll &y){    if(b == 0)    {        x = 1 ;        y = 0 ;        return a ;    }    ll r = exgcd(b , a%b , x , y) ;    ll tmp = x  ;    x = y;    y = tmp - a/b*y ;    return r ;}int main(){  //  freopen("in.txt" ,"r" , stdin) ;    int  n , m ;    while(~scanf("%d%d" , &n , &m))    {        ll st = 0  , en = 0 ;        ll sum = 0 ;        for(int i = 1;i <= n;i++)        {            int t ;            scanf("%d" , &t) ;            sum += t ;            int mi = st ;            int ma = en ;            if(st >= t)            mi = st - t ;            else if(en >= t)            mi = 0 ;            else mi = t - en ;            if(m - en >= t)            ma = en + t ;            else if(m - st >= t)            ma = m ;            else            ma = 2*m - st - t ;            st = mi ;            en = ma ;        }        ll ans = 0  ;        c[0] = 1 ;        for(int i = 1;i <= m;i++)        {            ll x , y ;            exgcd((ll)i  ,mod , x , y) ;            c[i] = x*(ll)(m-i+1)%mod*c[i-1]%mod ;        }        st = (st&1) == (sum&1) ? st : (st+1) ;        for(int i = st;i <= en;i+= 2)        ans = (ans + c[i])%mod ;        cout<<(ans+mod)%mod<<endl;    }    return  0 ;}

0 0
原创粉丝点击