嘘~ 正在从服务器偷取页面 . . .

UVA1118 Binary Stirling Numbers 题解


UVA1118 Binary Stirling Numbers 题解

题目链接:Binary Stirling Numbers 或者 SP106

题意

The Stirling number of the second kind $S(n, m)$ represents 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:

We can compute $S(n, m)$​ using the recurrence,

but your task is slightly different:

给定整数 $n,m$ ,计算出 $S(n,m)$ 的奇偶性,也就是 $S(n,m) \bmod 2$ 。

输入:多组数据,$n,m$ 。输出:答案。

数据范围

$1 \le m \le n \le 10^9$ 。

首先

那么

可以作图如下(这个图怎么看上去是歪的啊

图中红线表示 $S(n-1,m-1)$ 到 $S(n,m)$ 的转移,蓝线表示 $S(n-1,m)$ 到 $S(n,m)$ 的转移。

因为只有红线能增加 $m$ ,所以从 $(0,0)$ 到 $(n,m)$ 的转移中,红线经过了 $m$ 次,则蓝线经过了 $n-m$​ 次。

而对于点 $(n,m)$ ,能用的蓝线的数量 $k=\left\lfloor\frac{m+1}{2}\right\rfloor$ ,即将 $n-m$ 次蓝线划分为不超过 $k$ 个连续段。

于是问题转化为组合数的奇偶性问题。

根据 Lucas 定理,

这实际上就是在考察 $m$ 的每个二进制位

可以发现,当且仅当 $n,m$ 这一位同时为 $1$ ,答案才可能是 $1$ 。

即,当且仅当 $(n \land m)=m$ ($\land$ 表示二进制按位与) ,$\binom{n}{m} \bmod 2=1$​ 。

于是原题就可以做了。

单次询问时间复杂度 $\mathcal{O}(1)$

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)())

void solve()
{
    int n, m; cin >> n >> m;
    if(!n && !m) { cout << "1\n"; return; }
    if(!n || !m || n < m) { cout << "0\n"; return; }
    int t = (m + 1) / 2 - 1; cout << ((t & n - m + t) == t) << '\n';
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    int qwq; cin >> qwq; while(qwq--) solve();
    return 0;
}

参考文献

[1] https://www.luogu.com.cn/article/u3g9is8w

[2] https://www.luogu.com.cn/article/7cxxhl0r


题外话


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录