题意

给出n个长度为20的二进制数和数字k,每次询问给出一个二进制数,问从n个数中挑k个数(不能重复)的按位或能包含询问的组合有多少个。数字均小于等于5E5,1s。


思考

强行算出2^20个答案,再O(1)询问。

可知按位或的FWT能够将两个数组融合成新的数组。假设Fk表示挑出k个数字能组成的所有可能的,A为原始的桶数组,可知Fk[i]=(Fk-1 或运算FWT A)[i]-(k-1)Fk-1[i],后面减法的目的是减去数被重复选择的部分。

再观察FWT其实是线性变换,因此Fk[i]可以预先乘上k方便下一次计算。因此最开始只要乘上某个组合数即可。

最后根据按位与FWT可得到所有的答案。总复杂度O(nlogn)。


代码

 #pragma GCC optimize 2
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long int ll;
const int maxn=1E6+5E5+;
const int LEN=;
const int G=<<LEN;
ll n,k,m,a[maxn],b[maxn],c[maxn],d[maxn];
ll fac[maxn],inv[maxn];
string str;
inline int get(string str)
{
int sum=;
for(int i=;i<LEN;++i)
sum=sum*+str[i]-'';
return sum;
}
ll qpow(ll x,ll y)
{
ll ans=,base=x;
while(y)
{
if(y&)
ans=ans*base%mod;
base=base*base%mod;
y>>=;
}
return ans;
}
void init()
{
fac[]=;
for(int i=;i<=;++i)
fac[i]=fac[i-]*i%mod;
inv[]=qpow(fac[],mod-);
for(int i=-;i>=;--i)
inv[i]=inv[i+]*(i+)%mod;
}
void FWT(ll*A,int t1,int t2)
{
for(int len=;len<=G;len<<=)
for(int i=;i<G/len;++i)
for(int j=;j<len/;++j)
{
ll a=A[i*len+j],b=A[i*len+j+len/];
A[i*len+j]=(a+b*t1)%mod;
A[i*len+j+len/]=(b+a*t2)%mod;
}
}
template<class T>void copy(T*a,T*b,int x)
{
for(int i=;i<x;++i)
a[i]=b[i];
}
int main()
{
ios::sync_with_stdio(false);
init();
cin>>n>>k>>m;
for(int i=;i<=n;++i)
{
cin>>str;
++a[get(str)];
}
copy(c,a,G);
FWT(a,,);
for(int i=;i<G;++i)
{
if(a[i]>=k)
a[i]=fac[a[i]]*inv[a[i]-k]%mod;
else
a[i]=;
}
FWT(a,,-);
/*
for(int i=2;i<=k;++i)
{
copy(d,a,G);
FWT(a,0,1);
copy(b,c,G);
FWT(b,0,1);
for(int j=0;j<G;++j)
a[j]=a[j]*b[j]%mod;
FWT(a,0,-1);
for(int j=0;j<G;++j)
a[j]=(a[j]-d[j]*(i-1)+mod)%mod;
}
*/
FWT(a,,);
while(m--)
{
cin>>str;
cout<<a[get(str)]*inv[k]%mod<<endl;
}
return ;
}

最新文章

  1. C#多态“说来也说”——逻辑层BLL中的多态使用
  2. 我的屌丝giser成长记-研二篇
  3. 虚拟机解决Device eth0 does not seem to be present 问题。
  4. 【POJ3691】DNA repair(AC自动机,DP)
  5. DFS+剪枝 HDOJ 5323 Solve this interesting problem
  6. [Swift 语法点滴]——数组参数
  7. linux -- 启动时启动服务或者执行命令
  8. Android(java)学习笔记261:JNI之编写jni程序适配所有处理器型号
  9. linux 6.4平台利用rman迁移oracle 11g r2数据库
  10. js表格排序 &amp; 去除字符串空格
  11. Quartz学习——Quartz大致介绍(一)
  12. bzoj4476 [Jsoi2015]送礼物
  13. 448. Find All Numbers Disappeared in an Array&amp;&amp;645. Set Mismatch
  14. A. 【UR #17】滑稽树上滑稽果
  15. React native 之设置IOS的图标,名称和启动图(下篇文章会讲到RN的android的相关设置)
  16. TPshop的规格表设计原理机制
  17. python图片处理(二)
  18. SGU 169 Numbers (找规律)
  19. BZOJ2330:[SCOI2011]糖果(差分约束)
  20. 学习HTML 第一节.小试牛刀

热门文章

  1. 【sublime】Pretty Json插件的安装与配置使用
  2. 18.函数复习,文件处理b模式(二进制处理),文件处理其他高级玩法
  3. 第四阶段:1.从零打造一款社区web产品
  4. 记mysql一次莫名的1062错误
  5. 搜索排序-learning to Rank简介
  6. linux大盘格式化分区
  7. 20191017-6 alpha week 2/2 Scrum立会报告+燃尽图 05
  8. springboot + freemarker 实现计算器
  9. win7技巧
  10. 解决springmvc报错,java.lang.IllegalArgumentException:No converter found for return value of type: class .......