题目链接

\(Description\)

给定\(n\)个正整数\(a_i\)。求有多少个子序列\(a_{i_1},a_{i_2},...,a_{i_k}\),满足\(a_{i_1},a_{i_2},...,a_{i_k}\) \(and\)起来为\(0\)。

\(n\leq10^6,\quad 0\leq a_i\leq10^6\)。

\(Solution\)

这个数据范围。。考虑按位容斥:

令\(g_x\)表示\(x\)的二进制表示中\(1\)的个数,\(f_x\)表示有多少个\(a_i\)满足\(a_i\&x=x\)。

想要让选出来的子序列最终\(and\)和为\(x\),那么只能从这\(f_x\)个数中选。

所以\(Ans=\sum_{x=0}^{lim}(-1)^{g_x}(2^{f_x}-1)\)。

那么如何求\(f_x\)?

\(a_i\&x=x\),即\(x\)是\(a_i\)的子集,所以对\(f_x\)枚举超集更新即可。复杂度\(O(2^nn)\)。

注意因为写法问题数组要开两倍。

又一不小心一个rank1...

//62ms	35500KB
#include <cstdio>
#include <cctype>
#include <algorithm>
#define MAXIN 500000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define mod 1000000007
#define lb(x) (x&-x)
#define Add(x,v) (x+=v)>=mod&&(x-=mod)
typedef long long LL;
const int N=3e6+5; int bit[N],pw[N],f[N];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
} int main()
{
int n=read(),lim=0;
for(int t,i=1; i<=n; ++i) ++f[t=read()],lim=std::max(lim,t);
pw[0]=1;
for(int i=1; i<=n; ++i) pw[i]=pw[i-1]<<1, pw[i]>=mod&&(pw[i]-=mod);
for(int i=0; 1<<i<=lim; ++i)
for(int s=0; s<=lim; ++s)
if(!(s>>i&1)) Add(f[s],f[s|(1<<i)]);
LL ans=0;
for(int i=1; i<=lim; ++i) bit[i]=bit[i^lb(i)]^1;
for(int i=0; i<=lim; ++i) ans+=bit[i]?mod-pw[f[i]]+1:pw[f[i]]-1;
printf("%I64d\n",ans%mod); return 0;
}

Codeforces.449D.Jzzhu and Numbers(容斥 高维前缀和)的更多相关文章

  1. Codeforces 449D Jzzhu and Numbers(高维前缀和)

    [题目链接] http://codeforces.com/problemset/problem/449/D [题目大意] 给出一些数字,问其选出一些数字作or为0的方案数有多少 [题解] 题目等价于给 ...

  2. Codeforces 449D Jzzhu and Numbers

    http://codeforces.com/problemset/problem/449/D 题意:给n个数,求and起来最后为0的集合方案数有多少 思路:考虑容斥,ans=(-1)^k*num(k) ...

  3. BZOJ4036:按位或 (min_max容斥&高维前缀和)

    Description 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行或(c++,c的|,pascal 的or)操作.选择数字i的概率是p[i].保证0&l ...

  4. [luogu 3175] [HAOI2015]按位或(min-max容斥+高维前缀和)

    [luogu 3175] [HAOI2015]按位或 题面 刚开始你有一个数字0,每一秒钟你会随机选择一个[0,2^n-1]的数字,与你手上的数字进行按位或运算.问期望多少秒后,你手上的数字变成2^n ...

  5. luoguP3175 [HAOI2015]按位或 min-max容斥 + 高维前缀和

    考虑min-max容斥 \(E[max(S)] = \sum \limits_{T \subset S} min(T)\) \(min(T)\)是可以被表示出来 即所有与\(T\)有交集的数的概率的和 ...

  6. [Hdu-6053] TrickGCD[容斥,前缀和]

    Online Judge:Hdu6053 Label:容斥,前缀和 题面: 题目描述 给你一个长度为\(N\)的序列A,现在让你构造一个长度同样为\(N\)的序列B,并满足如下条件,问有多少种方案数? ...

  7. Codeforces 595B. Pasha and Phone 容斥

    B. Pasha and Phone time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  8. Codeforces Round #258 (Div. 2) 容斥+Lucas

    题目链接: http://codeforces.com/problemset/problem/451/E E. Devu and Flowers time limit per test4 second ...

  9. Relatively Prime Powers CodeForces - 1036F (莫比乌斯函数容斥)

    Relatively Prime Powers CodeForces - 1036F Consider some positive integer xx. Its prime factorizatio ...

随机推荐

  1. python网络爬虫笔记(六)

    1.获取属性如果不存在就返回404,通过内置一系列函数,我们可以对任意python对象进行剖析,拿到其内部数据,但是要注意的是,只是在不知道对象信息的时候,我们可以获得对象的信息. 2.实例属性和类属 ...

  2. 设置IDEA中的web

  3. SQL 查询表的第一条数据 和 最后一条数据

    方法一: 使用TOP SELECT TOP 1 * FROM user; SELECT TOP 1 * FROM user order by id desc; 方法二: 使用LIMIT SELECT ...

  4. linux dig 命令使用方法

    ref:https://www.imooc.com/article/26971?block_id=tuijian_wz dig 命令主要用来从 DNS 域名服务器查询主机地址信息. 查询单个域名的 D ...

  5. 关于64位 MS SQL 导入导出 Oracle 引发 ORA-06413 的解决方法

    如果在X64系统下我们想利用 MS SQL 的DTS导入导出 Oracle 数据,由 oracle 不支持路径中包含")",会引发 ORA-06413:连接未打开错误 解决的办法很 ...

  6. Quartz.net 2.4.1 使用记录

    项目需要开发一个调度任务工具,用于

  7. delphi TreeView 从数据库添加节点的四种方法

    方法一:delphi中递归算法构建treeView 过程:通过读取数据库中table1的数据,来构建一颗树.table1有两个字段:ID,preID,即当前结点标志和父结点标志.所以整个树的表示为父母 ...

  8. POJ 2914 Minimum Cut【最小割 Stoer-Wangner】

    题意:求全局最小割 不能用网络流求最小割,枚举举汇点要O(n),最短增广路最大流算法求最大流是O(n2m)复杂度,在复杂网络中O(m)=O(n2),算法总复杂度就是O(n5):就算你用其他求最大流的算 ...

  9. codeforces 1037

    题解: E-trips 哎哎哎好傻逼啊 没有想到算不能的一直在想怎么算能的 太傻逼了 其实很简单 我们只需要对好友<=k的首先dfs一下给他连接着的朋友-1 然后如果小于了就递归下去 这个正确性 ...

  10. WebApi 得到提交过来的 post 数据

    byte[] byts = new byte[System.Web.HttpContext.Current.Request.InputStream.Length]; System.Web.HttpCo ...