Solution -「洛谷 P3773」「CTSC 2017」吉夫特

cirnovsky /

§ Description

Link.

求满足

i=2k(abi1abi)mod2=(ab1ab2)×(ab2ab3)×(abk1abk)mod2>0\prod _{i=2}^{k} \binom{a_{b_{i-1}}}{a_{b_i}} \mod 2 = \binom{a_{b_1}}{a_{b_2}} \times \binom{a_{b_2}}{a_{b_3}} \times \cdots \binom{a_{b_{k-1}}}{a_{b_k}} \mod 2 > 0

的子序列个数。

§ Solution

哇哦。

    i=2k(abi1abi)i=2k(abi12abi2)×(abi1mod2abimod2)(mod2)\begin{aligned} &\ \ \ \ \prod_{i=2}^{k}{a_{b_{i}-1}\choose a_{b_{i}}} \\ &\equiv\prod_{i=2}^{k}{\lfloor\frac{a_{b_{i}-1}}{2}\rfloor\choose\lfloor\frac{a_{b_{i}}}{2}\rfloor}\times{a_{b_{i}-1}\bmod2\choose a_{b_{i}}\bmod2} \end{aligned} (\operatorname{mod} 2)

式子后面的 (abi1mod2abimod2)\dbinom{a_{b_{i}-1}\bmod2}{a_{b_{i}\bmod2}} 一共有四种情况,其中只有 (01)=0\dbinom{0}{1}=0。其他都为 11

意味着只要出现 abi10mod2a_{b_{i}-1}\equiv0\bmod2abi1mod1a_{b_{i}}\equiv1\bmod1 的情况,整个式子就为零了。

结论:(nm)0 (mod2)\dbinom{n}{m}\equiv0\space(\operatorname{mod}2) 当且仅当 nbitandm=mn\operatorname{bitand}m=m

证明(也许不是特别严谨):我们可以知道:

(nm)=(n2m2)×(nmod2mmod2)=(n22m22)×(n2mod2m2mod2)×(nmod2mmod2)={n\choose m}={\lfloor\frac{n}{2}\rfloor\choose\lfloor\frac{m}{2}\rfloor}\times{n\bmod 2\choose m\bmod2}={\lfloor\frac{\lfloor\frac{n}{2}\rfloor}{2}\rfloor\choose\lfloor\frac{\lfloor\frac{m}{2}\rfloor}{2}\rfloor}\times {\lfloor\frac{n}{2}\rfloor\bmod2\choose\lfloor\frac{m}{2}\rfloor\bmod2}\times{n\bmod 2\choose m\bmod2}=\cdots

我们发现:

(n22m22){\lfloor\frac{\lfloor\frac{\lfloor\frac{n}{2}\rfloor}{2}\rfloor}{\cdots}\rfloor\choose\lfloor\frac{\lfloor\frac{\lfloor\frac{m}{2}\rfloor}{2}\rfloor}{\cdots}\rfloor}

这一坨,就是在一直进行二进制移位,shr1\operatorname{shr}1

那么我们可以得出一个结论:如果对于我们记 (n)k(n)_{k} 表示 nn 在二进制意义下的第 kk 位。(n)k[0,1](n)_{k}\in[0,1]

那么对于 i\forall i,有 (n)i=0(n)_{i}=0(m)i=1(m)_{i}=1,那么 (nm)0 (mod2)\dbinom{n}{m}\equiv0\space(\operatorname{mod} 2)

所以 nbitandm=mn\operatorname{bitand}m=m,证毕。

我们题目要求的是最后算出来是个奇数,那么就不能存在 abi1bitandabi=abia_{b_{i}-1}\operatorname{bitand}a_{b_{i}}=a_{b_{i}}

也就是 abia_{b_{i}}abi1a_{b_{i}-1} 的子集。

接下来我们可以设计一个 DP,我们设 fif_{i} 为以 aia_{i} 为开头的答案。

那么转移就是加法原理:

fi=fi+fj,jaitj>if_{i}=f_{i}+f_{j},j\in a_{i}\wedge t_{j}>i

其中 tit_{i} 表示 ii 在序列中的位置。

时间复杂度由二项式定理可知是 Θ(3log2max{ai})\Theta(3^{\log_{2}\max\{a_{i}\}})

#include <cstdio>
#define mod ( 1000000007 )

const int MAXN = 250000 + 5;

int N;
int val[MAXN], dp[MAXN];
int buc[MAXN];

int main( ){
	scanf( "%d", &N ); for( int i = 1; i <= N; ++ i ){ scanf( "%d", &val[i] ); buc[val[i]] = i; }
	int Ans = 0;
	for( int i = N; i; -- i ){
		dp[i] = 1;
		for( int j = val[i] & ( val[i] - 1 ); j; j = ( j - 1 ) & val[i] ){
			if( buc[j] > i )	dp[i] = ( dp[i] + dp[buc[j]] ) % mod;
		}
		Ans = ( Ans + dp[i] ) % mod;
	}
	printf( "%d\n", ( Ans - N + mod ) % mod );
	return 0;
}