【题目链接】 http://codeforces.com/problemset/problem/449/D

【题目大意】

  给出一些数字,问其选出一些数字作or为0的方案数有多少

【题解】

  题目等价于给出一些集合,问其交集为空集的方案数,
  我们先求交集为S的方案数,记为dp[S],发现处理起来还是比较麻烦,
  我们放缩一下条件,求出交集包含S的方案数,记为dp[S],
  我们发现dp[S],是以其为子集的方案的高维前缀和,
  我们逆序求高维前缀和即可,之后考虑容斥,求出交集为0的情况,
  我们发现这个容斥实质上等价于高维的前缀差分,
  那么我们利用之前的代码,修改一下参数就能得到答案。

【代码】

#include <cstdio>
#include <algorithm>
using namespace std;
const int mod=1000000007;
typedef long long LL;
int all,n,m,x;
struct data{
int val;
data operator +(const data &rhs)const{
int t_val=val+rhs.val;
if(t_val>=mod)t_val-=mod;
if(t_val<0)t_val+=mod;
return data{t_val};
}
data operator *(const int &rhs)const{
int t_val=val*rhs;
return data{t_val};
}
}dp[(1<<20)+10];
LL pow(LL a,LL b,LL p){LL t=1;for(a%=p;b;b>>=1LL,a=a*a%p)if(b&1LL)t=t*a%p;return t;}
void doit(data dp[],int n,int f){
for(int i=0;i<n;i++){
for(int j=all-1;j>=0;j--){
if(~j&(1<<i))dp[j]=dp[j]+dp[j|(1<<i)]*f;
}
}
}
int main(){
scanf("%d",&n);
all=(1<<20);
for(int i=0;i<n;i++){scanf("%d",&x);dp[x].val++;}
doit(dp,20,1);
for(int i=0;i<all;i++)dp[i].val=pow(2,dp[i].val,mod);
doit(dp,20,-1);
printf("%d\n",dp[0].val);
return 0;
}

最新文章

  1. nfc相关
  2. Spring基于注解ehCache缓存整合
  3. R语言向量
  4. 65. Reverse Integer &amp;&amp; Palindrome Number
  5. XML数据源快速开发框架——XmlFramwork
  6. SQL算术数字的默认类型
  7. pupper基线加固
  8. [backbone]backbone.js
  9. 解决ubuntu 14.04 下eclipse 3.7.2 不能启动,报Could not detect registered XULRunner to use 或 org.eclipse.swt.SWTError: XPCOM 等问题的处理
  10. nginx Location配置总结(转)
  11. mysql创建数据库(指定编码)
  12. Laravel5.2 下使用Form
  13. 在非MFC的win 32程序里面能够使用CString类
  14. U盘为什么还有剩余空间,但却提示说空间不够
  15. 1635: [Usaco2007 Jan]Tallest Cow 最高的牛
  16. sublime自动保存(失去焦点自动保存)
  17. 【JavaScript_轮播图】
  18. PHP针对数字的加密解密类,可直接使用
  19. Spark注册UDF函数,用于DataFrame DSL or SQL
  20. extjs技术

热门文章

  1. PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)
  2. kolakoski序列
  3. hadoop2.4.1伪分布式环境搭建
  4. 命令行创建KVM虚拟机
  5. Jmeter跨线程组传递变量
  6. sicily 1046. Plane Spotting
  7. Python爬虫数据处理
  8. [ python ] 项目:haproxy配置文件增删改查
  9. 使用js创建select option
  10. linux下环境变量设置的问题