hdu 4349 求C(n,0),C(n,1),C(n,2)...C(n,n).当中有多少个奇数 (Lucas定理推广)

Lucas定理:把n写成p进制a[n]a[n-1]a[n-2]...a[0],把m写成p进制b[n]b[n-1]b[n-2]...b[0],则C(n,m)与C(a[n],b[n])*C(a[n-1],b[n-1])*C(a[n-2],b[-2])*....*C(a[0],b[0])模p同余。

即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)

这题是求C(n,0),C(n,1),C(n,2)...C(n,n).当中有多少个奇数
也是就是说 求C(n,m)%2==1 的个数 m的范围是0-n

C(n,m)%2,那么由lucas定理,我们可以写成二进制的形式观察

比如n=010 m为000 001 010
最终结果为 1+0+1=2
因为 C(0,1)=0
所以C(0,0)* C(1,0)*C(0,1)= 0
所以n = 010 中的0 不能对应m中的1 否则就会为了
n = 010 中的1 可以对应m中的0 或 1
也就变成了求n的二进制中有多少个1 求1的个数
最后结果为 2^(n中1的个数)

Sample Input
1 //n
2
11

Sample Output
2
2
8

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 # include <string>
 6 # include <cmath>
 7 # include <queue>
 8 # include <list>
 9 # define LL long long
10 using namespace std ;
11 
12 
13 int main()
14 {
15     //freopen("in.txt","r",stdin) ;
16     int n ;
17     while(scanf("%d",&n)!=EOF)
18     {  
19         int cnt=0;  
20         while(n)
21         {  
22             if(n&1)  
23                cnt++;  
24             n>>=1;  
25         }  
26         printf("%d\n",1<<cnt);  
27     }  
28     return 0;
29 }
View Code

 

posted @ 2015-09-20 21:48  __Meng  阅读(251)  评论(0编辑  收藏  举报