【POJ1430】Binary Stirling Numbers(第二类斯特林数,组合数)
求 \(\begin{Bmatrix}n\\m\end{Bmatrix}\bmod 2\) 的值。
由第二类斯特林数的递推公式:
可知:
我们把这个转移图给画出来:(图来自于 rui_er)
首先,若 \(m\) 为偶数,则 \(\begin{Bmatrix}n\\m\end{Bmatrix}\equiv\begin{Bmatrix}n-1\\m-1\end{Bmatrix}\pmod 2\),所以我们默认 \(m\) 为奇数。
那么按照上面的转移图,从 \((0,0)\) 走到 \((n,m)\) 的路径数的奇偶性就是 \(\begin{Bmatrix}n\\m\end{Bmatrix}\) 的奇偶性,所以我们只需要求出从 \((0,0)\) 走到 \((n,m)\) 的路径数即可。
显然我们一共要走 \(n\) 条边,其中有 \(m\) 条边是红边,那么有 \(n-m\) 条绿边。
注意到除了一开始走的第一条红边之外其它红边都是一走就连续走一组(两条)的,所以如果我们把第一条红边也算作一组,那么就共有 \(\dfrac{m+1}{2}\) 组。
组与组之间、最后一组后面,这 \(\dfrac{m+1}{2}\) 个地方都可以走若干条(包括 \(0\) 条)绿边。
现在要把 \(n-m\) 条绿边分配到这 \(\dfrac{m+1}{2}\) 个地方,设 \(a=n-m,b=\dfrac{m+1}{2}\),那么由插板法可知方案数为 \(\dbinom{a+b-1}{b-1}\),这个就是从 \((0,0)\) 走到 \((n,m)\) 的路径数。
接下来怎么办呢?
引理:\(\dbinom{n}{m}\) 为奇数当且仅当 \(n\operatorname{bitand}m=m\)。
证明:
由卢卡斯定理:
你发现 \(n\bmod 2\) 其实就是 \(n\) 二进制下第 \(0\) 位;
\(\lfloor\dfrac{n}{2}\rfloor\) 就是 \(n\) 右移一位,\(\lfloor\dfrac{n}{2}\rfloor\bmod 2\) 就是 \(n\) 二进制下第 \(1\) 位;
……
所以如果我们记 \((n)_k\) 表示 \(n\) 二进制下第 \(k\) 位,那么:(设 \(n,m\) 最高位为第 \(K\) 位)
所以 \(\dbinom{n}{m}\equiv 1\pmod 2\) 当且仅当 \(\forall i\in [0,K],\dbinom{(n)_i}{(m)_i}=1\)。
又由于 \((n)_i,(m)_i\in\{0,1\}\),手摸可知 \(\dbinom{0}{0}=\dbinom{1}{0}=\dbinom{1}{1}=1\),\(\dbinom{0}{1}=0\),发现恰好前三个都满足 \((n)_i\operatorname{bitand}\;(m)_i=(m)_i\),所以条件等价于 \(n\operatorname{bitand}m=m\)。
证毕。
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int t,n,m;
int main()
{
t=read();
while(t--)
{
n=read(),m=read();
if(!m)
{
puts(n?"0":"1");
continue;
}
if(!n||m>n)
{
puts("0");
continue;
}
if(!(m&1)) n--,m--;
int a=n-m,b=(m+1)/2;
int nn=a+b-1,mm=b-1;
puts((nn&mm)==mm?"1":"0");
}
return 0;
}