Solution -「SP 106」BINSTIRL
§ Description
Link.
求 {nm}mod2
§ Solution
求
{nm}mod2=({n−1m−1}+m{n−1m})mod2=⎩⎨⎧{n−1m−1}mod2,m≡0 (mod2)({n−1m−1}+{n−1m})mod2,m≡1 (mod2)
m≡1 (mod2) 的情况为组合数的递推。
转化一下,把填表转移换成刷表,即
-
当 m≡0 (mod2) 时,{nm} 转移到 {n+1m+1}。
-
当 m≡1 (mod2) 时,{nm} 转移到 {n+1m+1} 和 {n+1m}。
那么这个题目就转化成了在表格上 (0,0) 走到 (n,m) 的路径条数 mod2 问题。
两种情况都可以转移到 {n+1m+1},为了方便起见,我们定义这种情况为向右上转移,把 {n+1m} 定义为向上转移。
因为我们转移只能向上或右上走,所以只会走 n 步,其中 m 次向右上转移,n−m 次向右转移。
我们一共有 ⌊2m+1⌋ 次机会向右转移(只能从奇数走)。
相当于我们现在需要把转移的过程分成 n−m 段,每一段的内部全部都是向右上转移,这样我们才能到达 (n,m)。
用盒子与球的语言来描述,就是一共就有 n−m+⌊2m+1⌋ 个球(这里理解起来其实特别麻烦)(不过只是对于我这种组合差的人),分成 ⌊2m+1⌋ 段,隔板即可。
于是 {nm}mod2=(⌊2m+1⌋−1n−m+⌊2m+1⌋−1)mod2。
关于组合数奇偶性,我这篇博客里写过,再贴上来:
结论:(mn)≡0 (mod2) 当且仅当 nbitandm=m。
证明(也许不是特别严谨):我们可以知道:
(mn)=(⌊2m⌋⌊2n⌋)×(mmod2nmod2)=(⌊2⌊2m⌋⌋⌊2⌊2n⌋⌋)×(⌊2m⌋mod2⌊2n⌋mod2)×(mmod2nmod2)=⋯
我们发现:
(⌊⋯⌊2⌊2m⌋⌋⌋⌊⋯⌊2⌊2n⌋⌋⌋)
这一坨,就是在一直进行二进制移位,shr1。
那么我们可以得出一个结论:如果对于我们记 (n)k 表示 n 在二进制意义下的第 k 位。(n)k∈[0,1]
那么对于 ∀i,有 (n)i=0 且 (m)i=1,那么 (mn)≡0 (mod2)。
所以 nbitandm=m,证毕。
答案显然。
#include <cstdio>
int N, M;
int main () {
int TC; scanf ( "%d", &TC ); while ( TC -- > 0 ) {
scanf ( "%d%d", &N, &M );
if ( ! N && ! M ) puts ( "1" );
else if ( ! N || ! M || N < M ) puts ( "0" );
else if ( ( ( N - M + ( ( M + 1 ) >> 1 ) - 1 ) & ( ( ( M + 1 ) >> 1 ) - 1 ) ) == ( ( ( M + 1 ) >> 1 ) - 1 ) ) puts ( "1" );
else puts ( "0" );
}
return 0;
}