【poj1430】Binary Stirling Numbers(斯特林数+组合数)

传送门

题意:
\(S(n,m)\% 2\)的值,\(n,m\leq 10^9\),其中\(S(n,m)\)是指第二类斯特林数。

思路:
因为只需要关注奇偶性,所以递推式可以写为:

  • \(m\)为偶数,\(S(n,m)=S(n-1,m-1)\);
  • \(m\)为奇数,\(S(n,m)=S(n-1,m-1)+S(n-1,m)\)

观察第二个式子,和组合数的递推公式一模一样。所以我们可以联想到组合数。

将上述递推式子前面几项的值写出来,会发现偶数列错了前面奇数列一列,若只看奇数列,则为杨辉三角的形式。
那么将\(S(n,m)\)写成组合数的形式就为:

\[S(n,m)=C(n-\lfloor\frac{m}{2}\rfloor-1,\lceil\frac{m}{2}\rceil-1) \]

具体怎么得出来的在纸上画一画即可。
接下来就关系\(C(n,m)\)的奇偶性,然后有个结论:

  • \(n\&m=m\),那么\(C(n,m)\)为奇数;否则为偶数。

然后判断一下就行。
代码如下:

/*
 * Author:  heyuhhh
 * Created Time:  2019/12/10 21:33:03
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1000 + 5;

int n, m;

void run(){
    cin >> n >> m;
    if((m & 1) == 0) {
        --n, --m;   
    }
    n = n - m / 2;
    m = (m + 1) / 2;
    --n, --m;
    if((n & m) == m) cout << 1 << '\n';
    else cout << 0 << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}
posted @ 2019-12-11 10:57  heyuhhh  阅读(369)  评论(0编辑  收藏  举报