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;
    }
    
  • 相关阅读:
    2.2.16锁对象的改变
    2.2.15内置类与同步:测试2
    2.2.14内置类与同步:测试1
    2.2.13内置类与静态内置类
    libev客户端
    Linux下sqlite3编程
    ds18b20驱动及应用程序
    ds18b20采集温度并上报服务器
    linux下GPRS模块ppp拨号上网
    linux下GPRS模块的应用程序
  • 原文地址:https://www.cnblogs.com/smyjr/p/11832302.html
Copyright © 2011-2022 走看看