标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1213 Accepted Submission(s):
449
1 /** 2 题意:把m个0,经过n次翻转,统计得到的情况总数。 3 1.对于第x个0来说,如果翻转偶数次,就是等于没有翻转。 4 首先,1出现的次数是连续的。 5 如果1的个数满足[ L , R ]的范围。 那么在L --》 R的范围也是合理的。 6 7 2.最后出现1的结果的个数 一定和原来翻转的个数和奇偶性相同。由1可以证明。 8 比如翻转 3 ,2 那么必然只会有奇数个1存在。 9 10 3.求出满足的最小1的个数,和最大1的个数,然后sum( C(m,i) i &1 == sum&1 ,sum =所以数的和 ); 11 12 C(n,m)%p,由于p是素数用Lucas定理来求. 13 **/ 14 #include<iostream> 15 #include<stdio.h> 16 #include<cstring> 17 #include<cstring> 18 #include<cstdlib> 19 using namespace std; 20 typedef __int64 LL; 21 22 const int maxn = 100000+1; 23 const LL p = 1000000009 ; 24 LL fac[maxn]; 25 void init() 26 { 27 fac[0] = 1; 28 for(int i=1;i<maxn;i++) 29 fac[i]=(fac[i-1]*i)%p; 30 } 31 LL pow_mod(LL a,LL b) 32 { 33 LL ans =1; 34 while(b) 35 { 36 if(b&1) ans=(ans*a)%p; 37 b=b>>1; 38 a=(a*a)%p; 39 } 40 return ans; 41 } 42 LL C(LL n,LL m) 43 { 44 if(m==0 || n==m) return 1; 45 LL sum1 = fac[n]; 46 LL sum2 =(fac[m]*fac[n-m])%p; 47 sum1 = (sum1*pow_mod(sum2,p-2))%p; 48 return sum1; 49 } 50 int main() 51 { 52 init(); 53 LL n,m; 54 LL Min,Max,k,ans,pp,q; 55 while(scanf("%I64d%I64d",&n,&m)>0) 56 { 57 Min = Max = 0; 58 for(k=1;k<=n;k++) 59 { 60 scanf("%I64d",&ans); 61 //最少的1 62 if(Min>=ans) pp = Min - ans;/**尽可能的让1变成0**/ 63 else if(Max>=ans) pp = ( (Max&1) ==(ans&1) )? 0:1; 64 /** 区间[ Min ,Max ] 包含ans,判断奇偶性能否取到就行 **/ 65 else pp = ans -Max; 66 /**比Max都大,只能把所以1变成0,部分0变成1了。**/ 67 68 //最多的1 69 if(Max+ans<=m) q = Max+ans;/**尽可能的让0变成1**/ 70 else if(Min+ans<=m) q = ( ((Min+ans)&1)==(m&1) ) ? m:m-1; 71 /** Min+ans<=m<=Max+ans 所以,m可能取到,但是要判断奇偶性 **/ 72 /**这里用Max+ans 或者 Min+ans都一样的**/ 73 else q = 2*m -(Min+ans); 74 /** Min+ans>m ,那么只能2*m-(Min+ans) **/ 75 76 Min =pp; 77 Max =q; 78 } 79 LL sum = 0; 80 for(LL i=Min;i<=Max;i=i+2) 81 { 82 sum = (sum+C(m,i))%p; 83 } 84 printf("%I64d\n",sum); 85 } 86 return 0; 87 }
标签:
原文地址:http://www.cnblogs.com/tom987690183/p/3871132.html