poj 1430 Binary Stirling Numbers

Binary Stirling Numbers
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 1761   Accepted: 671

Description

The Stirling number of the second kind S(n, m) stands for the number of ways to partition a set of n things into m nonempty subsets. For example, there are seven ways to split a four-element set into two parts: 

{1, 2, 3} U {4}, {1, 2, 4} U {3}, {1, 3, 4} U {2}, {2, 3, 4} U {1}


{1, 2} U {3, 4}, {1, 3} U {2, 4}, {1, 4} U {2, 3}.


There is a recurrence which allows to compute S(n, m) for all m and n. 

S(0, 0) = 1; S(n, 0) = 0 for n > 0; S(0, m) = 0 for m > 0;
S(n, m) = m S(n - 1, m) + S(n - 1, m - 1), for n, m > 0.


Your task is much "easier". Given integers n and m satisfying 1 <= m <= n, compute the parity of S(n, m), i.e. S(n, m) mod 2. 


Example 

S(4, 2) mod 2 = 1.


Task 

Write a program which for each data set: 
reads two positive integers n and m, 
computes S(n, m) mod 2, 
writes the result. 

Input

The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 200. The data sets follow. 

Line i + 1 contains the i-th data set - exactly two integers ni and mi separated by a single space, 1 <= mi <= ni <= 10^9. 

Output

The output should consist of exactly d lines, one line for each data set. Line i, 1 <= i <= d, should contain 0 or 1, the value of S(ni, mi) mod 2.

Sample Input

1

4 2

Sample Output

1

Source

 

可以转化成求C(N,M)来做。当然不是直接转化。

打出表看一下,发现是有规律的。

每一列都会重复一次。打表看一下吧。

思路:  

     s(n,m)   如果m是偶数  n=n-1; m=m-1;==>转化到它的上一个s(n-1,m-1);

          k=(m+1)/2;  n=n-k; m=m-k;求C(n,m)的奇偶性就可以了。(当然有很多书写方式,不一定要这样做。)

测试用的

 1 #include<iostream>

 2 #include<stdio.h>

 3 #include<cstring>

 4 #include<cstdlib>

 5 using namespace std;

 6 

 7 int dp[21][21];

 8 int cnm[21][21];

 9 void init()

10 {

11     int i,j;

12     dp[0][0]=1;

13     for(i=1;i<=20;i++) dp[i][0]=0;

14     for(i=1;i<=20;i++)

15         for(j=1;j<=i;j++)

16             dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j;

17     for(i=0;i<=15;i++)

18     {

19         for(j=0;j<=i;j++)

20             printf("%d ",(dp[i][j]&1));

21         printf("\n");

22     }

23 

24     cnm[0][0]=1;

25     for(i=1;i<=20;i++)

26     {

27         cnm[i][0]=1;

28         cnm[0][i]=1;

29     }

30     for(i=1;i<=20;i++)

31     {

32         for(j=1;j<=i;j++)

33         {

34             if(j==1) cnm[i][j]=i;

35             else if(i==j) cnm[i][j]=1;

36             else cnm[i][j]=cnm[i-1][j]+cnm[i-1][j-1];

37         }

38     }

39     for(i=0;i<=15;i++)

40     {

41         for(j=0;j<=i;j++)

42             printf("%d ",cnm[i][j]&1);

43         printf("\n");

44     }

45 }

46 int main()

47 {

48     init();

49     int n,m;

50     while(scanf("%d%d",&n,&m)>0)

51     {

52         printf("%d\n",dp[n][m]);

53     }

54     return 0;

55 }
View Code

ac代码

 1 #include<iostream>

 2 #include<stdio.h>

 3 #include<cstring>

 4 #include<cstdlib>

 5 using namespace std;

 6 

 7 int a[64],alen;

 8 int b[64],blen;

 9 void solve(int n,int m)

10 {

11     int i;

12     bool flag=false;

13     alen=0;

14     blen=0;

15     memset(a,0,sizeof(a));

16     memset(b,0,sizeof(b));

17     while(n)

18     {

19         a[++alen]=(n&1);

20         n=n>>1;

21     }

22     while(m)

23     {

24         b[++blen]=(m&1);

25         m=m>>1;

26     }

27     for(i=1; i<=alen; i++)

28     {

29         if(a[i]==0 && b[i]==1) flag=true;

30         if(flag==true) break;

31     }

32     if(flag==true)printf("0\n");

33     else printf("1\n");

34 }

35 int main()

36 {

37     int T;

38     int n,m,k;

39     scanf("%d",&T);

40     while(T--)

41     {

42         scanf("%d%d",&n,&m);

43         if(m%2==0)

44         {

45             n=n-1;

46             m=m-1;

47         }

48         k=(m+1)/2;

49         solve(n-k,m-k);

50     }

51     return 0;

52 }
View Code

 

你可能感兴趣的:(number)