zoukankan      html  css  js  c++  java
  • luogu P3773 [CTSC2017]吉夫特

    luogu

    这里的组合数显然要用( ext{lucas})定理来求,所以考虑( ext{lucas})定理的本质,即把(n,m)分别拆分成(p)进制串({a}{b}),然后(inom{n}{m}mod p=prod_i inom{a_i}{b_i}mod p)

    这题里(p=2),那么最后的(inom{n}{m})要为(1),当且仅当(m)的二进制串每一位(le n)二进制串的对应位,这相当于(n &)(按位与)( m=m),这是因为(prod_i inom{a_i}{b_i})中,所有(inom{a_i}{b_i})都要是(1),那么如果(exists i a_i=0,b_i=1),就会导致(inom{a_i}{b_i}=inom{0}{1}=0),那么最终的值就是(0),所以(m)二进制每一位都要(le n)的每一位.要求的实际上是长度(ge2)的子序列({s_1,s_2...s_k}),满足(forall iin[1,k-1] s_i&s_{i+1}=s_{i+1}),所以可以倒着扫一遍序列,然后对于当前数记(f_x)为子序列最后一项的值为(x)的方案,转移枚举(x)的子集转移

    #include<bits/stdc++.h>
    #define LL long long
    #define uLL unsigned long long
    #define db long double
    
    using namespace std;
    const int N=270000+10,mod=1000000007;
    int rd()
    {
    	int x=0,w=1;char ch=0;
    	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    	return x*w;
    }
    int n,a[N],f[N],ans;
    void ad(int &x,int y){x+=y,x-=x>=mod?mod:0;}
    
    int main()
    {
    	n=rd();
    	for(int i=1;i<=n;++i) a[i]=rd();
    	for(int i=n;i;--i)
    	{
    		for(int j=a[i];j;j=(j-1)&a[i]) ad(f[a[i]],f[j]);
    		ad(ans,f[a[i]]);
    		ad(f[a[i]],1);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    python基础学习笔记(五)
    python进阶学习笔记(一)
    python基础学习笔记(七)
    LoadRunner 技巧之 脚本设计
    python基础学习笔记(八)
    python基础学习笔记(三)
    python基础学习笔记(十一)
    性能测试知多少性能分析与调优的原理
    python基础学习笔记(十)
    python基础学习笔记(六)
  • 原文地址:https://www.cnblogs.com/smyjr/p/11832302.html
Copyright © 2011-2022 走看看