C - Binary Stirling Numbers解题报告(来自网络)


C - Binary Stirling Numbers
Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  POJ 1430

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

过了这题,我很兴奋,很久都没有这种感觉了。真的很舒服,不过这题我想了很久,数论的类型,的确有些难想。
好了,不多说了,说说这题到底怎么个解法吧!此题解法都是自己一步一步推过来的,希望对大家有启发。

首先由于%2的操作,我想到了f(n,m) = s(n,m)%2,假设一个f函数。于是s(n,m) = m * s(n-1,m)+ s(n-1,m-1) ==>
f(n,m) = s(n-1,m-1) (m为偶数); f(n,m) = f(n-1,m) + f(n-1,m-1)(m为奇数)。这样就可以将m给去掉,最后就是计算f(n,m)%2即可,必须想到怎么样得到f(n,m)。

怎么得到呢?这一步是比较难想的。我用递推,推了很久都不行,因为n,m实在太大了。于是我想到了先画个图,希望通过图形来表示它们的递推关系,果真很管用,我找到了。x轴表示n方向,y轴表示m方向,那么我可以看出其实就找从(0,0)点到(n,m)点有多少条路径,就是f(n,m) 的值了。如果大家将图画出来后,然后通过上式去找,我相信会找到公式了,最后其实得到的是一个组合 求出 f(n,m) = C(n-m, (m-1)/2)。不会很难找,大家就画画吧。

简化就是求C(n,m)%2 ,就是求C(n,m)的奇偶了。怎么求呢,这又是一个难点。C(n,m) = m!/(n!*(m-n)!){这个大家都知道的},这里就是要靠数学感觉了,我直接就想到了肯定和2因子有关,于是就得到这样一个结论,如果分子2因子的个数= 分母2因子的个数,那么就为奇数;否则就为偶数.。大家多想想,如果有些疑问,给我留言,现在就不在这里多说了。

相信大家如果看来上面且明白后,这个题AC就是2分钟内了。


#include <iostream>
using namespace std;

__int64 f(__int64 x)//计算x! 2的因子数目
{
 __int64 t =0;
 while(x)
 {
  x /= 2;
  t += x;
 }
 return t;
}
int main()
{
 int cas;
 __int64 n,m;
 scanf("%d",&cas);
 while(cas)
 {
  cas --;
  cin>>n>>m;
  n -= m;
  m = (m-1)/2;
  if(f(n+m) == f(n)+ f(m))
   printf("1\n");
  else
   printf("0\n");
 }
 return 0;
}



你可能感兴趣的:(c,网络,Integer,input,output,Numbers)