【数论】HDU 4869 Turn the pokers 费马小定理

题目链接
题意:
一个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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值