Problem 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.
ExampleS(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 2Sample Output
1
题意:t 组数据,每组给出第二类斯特林数的 S(n,m) 的 n、m,求其奇偶性
思路:
首先求 S(n,m) 的奇偶性实质就是求 S(n,m)%2
对于第二类斯特林数,首先有:S[i][j]=S[i−1][j−1]+j∗S[i−1][j]
那么在模 2 的情况下 ,有:
- 当 j 为偶数:S[i][j] ≡(S[i−1][j−1]%2)
- 当 j 为奇数:S[i][j] ≡((S[i−1][j−1]+S[i−1][j])%2)
于是,可以倒过来,即有:
- 当 j 为偶数时:S[i][j] 会被加到 S[i+1][j+1] 和 S[i+1][j]
- 当 j 为奇数时:S[i][j] 会被加到 S[i+1][j+1]
于是,令 a=n−m,b=(m+1)/2,则答案就相当于把 a 个相同的球分成 b 组,每组个数可以为 0 的方案总数,即:C(b−1,a+b−1)
然后利用 C(n,m) 为奇数时有 n&m=n 的结论,进行判断即可
最后,注意特判
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 10000+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;
int calc(int n,int m){
return (m&n)==n;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
if(n==0&&m==0)//特判
printf("1\n");
else if(n==0||m==0||n<m)//特判
printf("0\n");
else{
int a=n-m;
int b=(m+1)/2;
int res=calc(b-1,a+b-1);
printf("%d\n",res);
}
}
return 0;
}