zoukankan      html  css  js  c++  java
  • 【CF449D】Jzzhu and Numbers

    题目

    题目链接:https://codeforces.com/problemset/problem/449/D
    给定一个长度为 (n) 的序列 (a),求有多少种方案从 ({a_i}) 里面选出一个非空子集使这些数按位与起来为 (0)
    (n,a_ileq 10^6)

    思路

    我们可以把选择第 (i) 个数看做 and 上 (a_i),不选择第 (i) 个数看做 and 上 (mathrm{lim}=1048575)
    可以看做 (n) 个多项式进行 FWT,其中第 (i) 个多项式只有 (a_i)(mathrm{lim}) 两位为 (1),其余均为 (0)
    直接做 (n) 次 FWT 显然无法保证复杂度,考虑如何利用最多只有两位为 (1) 的性质。
    因为只有两位为 (1),所以 (FWT(A_i)_j=sum^{mathrm{lim}}_{k=0}c(j,k)[a_i=k]+c(j,mathrm{lim})=c(j,a_i)+c(j,mathrm{lim}))
    因为 and 卷积等价于 (FWT(A)_i=sum_{iin j}mathrm{val_j}),而 (mathrm{lim}) 包含 (1sim lim) 所有整数,所以

    [FWT(A_i)_j=c(j,a_i)+c(j,mathrm{lim})=1+c(j,a_i) ]

    我们只需要考虑第 (j) 项被多少 (a_i) 包含,因为只有这些 (a_i) 的贡献是 (2),其余均为 (1)。然后快速幂计算即可。
    那么直接上 and FWT 就好了。时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1050010,MOD=1000000007;
    const int C[2][2][2]={{{1,1},{0,1}},{{1,MOD-1},{0,1}}};
    int n,lim;
    ll f[N];
    
    ll fpow(ll x,ll k)
    {
    	ll ans=1;
    	for (;k;k>>=1,x=x*x%MOD)
    		if (k&1) ans=ans*x%MOD;
    	return ans;
    }
    
    void FWT(ll *f,int typ)
    {
    	for (int k=1;k<lim;k<<=1)
    		for (int i=0;i<lim;i+=(k<<1))
    			for (int j=0;j<k;j++)
    			{
    				ll x=f[i+j],y=f[i+j+k];
    				f[i+j]=(x*C[typ][0][0]+y*C[typ][0][1])%MOD;
    				f[i+j+k]=(x*C[typ][1][0]+y*C[typ][1][1])%MOD;
    			}
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1,x;i<=n;i++)
    	{
    		scanf("%d",&x);
    		f[x]++;
    	}
    	lim=1048576;
    	FWT(f,0);
    	for (int i=0;i<lim;i++)
    		f[i]=fpow(2,f[i]);
    	FWT(f,1);
    	printf("%lld",(f[0]%MOD+MOD)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    Linus Torvalds: 成功的项目源于99%的汗水与1%的创新
    web.py入门
    Python web框架有哪些
    python and 和 or
    python 安装ssh和Scrapy
    github使用
    github的.md格式文件
    python list comprehension twos for loop 嵌套for循环
    python 中函数参数传递形式
    python MySQLdb安装和使用
  • 原文地址:https://www.cnblogs.com/stoorz/p/14304491.html
Copyright © 2011-2022 走看看