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


    Description

    Link.

    求满足

    [prod _{i=2}^{k} inom{a_{b_{i-1}}}{a_{b_i}} mod 2 = inom{a_{b_1}}{a_{b_2}} imes inom{a_{b_2}}{a_{b_3}} imes cdots inom{a_{b_{k-1}}}{a_{b_k}} mod 2 > 0 ]

    的子序列个数。

    Solution

    哇哦。

    [egin{aligned} & prod_{i=2}^{k}{a_{b_{i}-1}choose a_{b_{i}}} \ &equivprod_{i=2}^{k}{lfloorfrac{a_{b_{i}-1}}{2} floorchooselfloorfrac{a_{b_{i}}}{2} floor} imes{a_{b_{i}-1}mod2choose a_{b_{i}}mod2} end{aligned} (operatorname{mod} 2) ]

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

    意味着只要出现 (a_{b_{i}-1}equiv0mod2)(a_{b_{i}}equiv1mod1) 的情况,整个式子就为零了。

    结论:(dbinom{n}{m}equiv0space(operatorname{mod}2)) 当且仅当 (noperatorname{bitand}m=m)

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

    [{nchoose m}={lfloorfrac{n}{2} floorchooselfloorfrac{m}{2} floor} imes{nmod 2choose mmod2}={lfloorfrac{lfloorfrac{n}{2} floor}{2} floorchooselfloorfrac{lfloorfrac{m}{2} floor}{2} floor} imes {lfloorfrac{n}{2} floormod2chooselfloorfrac{m}{2} floormod2} imes{nmod 2choose mmod2}=cdots ]

    我们发现:

    [{lfloorfrac{lfloorfrac{lfloorfrac{n}{2} floor}{2} floor}{cdots} floorchooselfloorfrac{lfloorfrac{lfloorfrac{m}{2} floor}{2} floor}{cdots} floor} ]

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

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

    那么对于 (forall i),有 ((n)_{i}=0)((m)_{i}=1),那么 (dbinom{n}{m}equiv0space(operatorname{mod} 2))

    所以 (noperatorname{bitand}m=m),证毕。

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

    也就是 (a_{b_{i}})(a_{b_{i}-1}) 的子集。

    接下来我们可以设计一个 DP,我们设 (f_{i}) 为以 (a_{i}) 为开头的答案。

    那么转移就是加法原理:

    [f_{i}=f_{i}+f_{j},jin a_{i}wedge t_{j}>i ]

    其中 (t_{i}) 表示 (i) 在序列中的位置。

    时间复杂度由二项式定理可知是 (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
    ", ( Ans - N + mod ) % mod );
    	return 0;
    }
    
  • 相关阅读:
    【微服务架构】SpringCloud组件和概念介绍(一)
    getaddrinfo()详解
    通货膨胀背景下,只能好好搞技术了
    到此为止,重新开始
    二级指针
    一篇关于spice vdagent和利用virtmanager配置spice的文章
    局域网中两台无线路由器联接配置方法图文教程
    ovirt简介
    IIS fastcgi 超时处理
    关于eclipse无法自动编译的问题
  • 原文地址:https://www.cnblogs.com/orchid-any/p/14035460.html
Copyright © 2020-2023  润新知