标签:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 100006 8 #define ll long long 9 #define MOD 1000000009 10 ll n,m; 11 ll a[N]; 12 ll fac[N]; 13 ll pow_mod(ll a,ll i) 14 { 15 if(i==0) 16 return 1%MOD; 17 ll t=pow_mod(a,i/2); 18 ll ans=t*t%MOD; 19 if(i%2==1) 20 ans=ans*a%MOD; 21 return ans; 22 } 23 ll work(ll m,ll i) 24 { 25 return ( (fac[m]%MOD)* ( pow_mod(fac[i]*fac[m-i]%MOD ,MOD-2)%MOD))%MOD; 26 } 27 28 int main() 29 { 30 fac[0]=1; 31 for(ll i=1;i<N;i++) fac[i]=fac[i-1]*i%MOD; 32 33 while(scanf("%I64d%I64d",&n,&m)==2) 34 { 35 ll x; 36 ll l=0,r=0; 37 ll p,q; 38 for(ll i=0;i<n;i++) 39 { 40 scanf("%I64d",&x); 41 //求下限 42 if(l>=x) p=l-x; 43 else if(r>=x) p=((l&1)==(x&1)?0:1); 44 else p=x-r; 45 46 //求上限 47 if(r+x<=m) q=r+x; 48 else if(l+x<=m) q=(((l+x)&1)==(m&1)?m:m-1); 49 else q=2*m-(l+x); 50 51 l=p; 52 r=q; 53 } 54 ll ans=0; 55 for(int i=l;i<=r;i+=2) 56 { 57 ans=ans+work(m,i); 58 ans%=MOD; 59 } 60 printf("%I64d\n",ans); 61 } 62 return 0; 63 }
附上大神的代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 #define mod 1000000009 7 #define LL __int64 8 #define maxn 100000+5 9 10 LL f[maxn]; 11 12 void set() 13 { 14 int i; 15 f[0] = 1; 16 for(i = 1; i<maxn; i++) 17 f[i] = (f[i-1]*i)%mod; 18 } 19 20 LL quickmod(LL a,LL b) 21 { 22 LL ans = 1; 23 while(b) 24 { 25 if(b&1) 26 { 27 ans = (ans*a)%mod; 28 b--; 29 } 30 b/=2; 31 a = ((a%mod)*(a%mod))%mod; 32 } 33 return ans; 34 } 35 36 int main() 37 { 38 int n,m,i,j,k,l,r,x,ll,rr; 39 set(); 40 while(~scanf("%d%d",&n,&m)) 41 { 42 l = r = 0; 43 for(i = 0; i<n; i++) 44 { 45 scanf("%d",&x); 46 //计算最小的1的个数,尽可能多的让1->0 47 if(l>=x) ll = l-x;//当最小的1个数大于x,把x个1全部翻转 48 else if(r>=x) ll = ((l%2)==(x%2))?0:1;//当l<x<=r,由于无论怎么翻,其奇偶性必定相等,所以看l的奇偶性与x是否相同,相同那么知道最小必定变为0,否则变为1 49 else ll = x-r;//当x>r,那么在把1全部变为0的同时,还有x-r个0变为1 50 //计算最大的1的个数,尽可能多的让0->1 51 if(r+x<=m) rr = r+x;//当r+x<=m的情况下,全部变为1 52 else if(l+x<=m) rr = (((l+x)%2) == (m%2)?m:m-1);//在r+x>m但是l+x<=m的情况下,也是判断奇偶,同态那么必定在中间有一种能全部变为1,否则至少有一张必定为0 53 else rr = 2*m-(l+x);//在l+x>m的情况下,等于我首先把m个1变为了0,那么我还要翻(l+x-m)张,所以最终得到m-(l+x-m)个1 54 55 l = ll,r = rr; 56 } 57 LL sum = 0; 58 for(i = l; i<=r; i+=2)//使用费马小定理和快速幂的方法求和 59 sum+=((f[m]%mod)*(quickmod((f[i]*f[m-i])%mod,mod-2)%mod))%mod; 60 printf("%I64d\n",sum%mod); 61 } 62 63 return 0; 64 }
hdu 4869 Turn the pokers(组合数+费马小定理)
标签:
原文地址:http://www.cnblogs.com/UniqueColor/p/4735403.html