[集训]FWT基础练习题
题意
给出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 ;
}
[集训]FWT基础练习题的更多相关文章
- Linux基础练习题(二)
Linux基础练习题(二) 1.复制/etc/skel目录为/home/tuer1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限. [root@www ~]# cp -r ...
- 珍藏的数据库SQL基础练习题答案
自己珍藏的数据库SQL基础练习题答案 一,基本表的定义与删除. 题1: 用SQL语句创建如下三张表:学生(Student),课程表(Course),和学生选课表(SC),这三张表的结构如表1-1到表1 ...
- Linux基础练习题之(四)
Linux基础练习题 请详细总结vim编辑器的使用并完成以下练习题 1.复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的 ...
- Python之基础练习题
Python之基础练习题 1.执行 Python 脚本的两种方式 2.简述位.字节的关系 解:8位是一个字节 3.简述 ascii.unicode.utf-8.gbk 的关系 4.请写出 “李杰” 分 ...
- shell基础练习题
shell 基础练习题 1.编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小 #!/bin ...
- js基础练习题(1)
1.字符串 视频教程地址: js基础练习题 1.如何连接两个或者两个以上字符串? var cssname = 'box' var num = 1 var html = '<div class=& ...
- 【视频+图文】Java经典基础练习题(三):输入3个整数,并将其由小到大输出
目录 一.视频讲解 二.思路分析 总结: 三.代码+详解+结果 四.彩蛋 能解决题目的代码并不是一次就可以写好的 我们需要根据我们的思路写出后通过debug模式找到不足再进行更改 多次测试后才可得到能 ...
- python基础练习题(九九乘法表)
又把python捡起来了,动手能力偏弱,决定每日一练,把基础打好! ------------------------------------------------------------------ ...
- javaScript基础练习题-下拉框制作
1.基础回顾 如何让一个段javascript在文档加载后执行,(因为自己忘了,所以顺便复习一下) window.onload = function(){}; <!DOCTYPE html PU ...
随机推荐
- PDF.JS 读取文件流前端展示 C#
最近再搞PDF得展示问题,因为aspose.pdf成本太高,只能使用pdf.js这个开源强大的前端东东了. 在百度了很久后 网上大都是node,java,php的事例,有位大哥的是C#的后台代码按他写 ...
- HDU5618 Jam's problem again CDQ分治
Jam's problem again CDQ分治 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5618 题意: \[ 有n 个元素,第 i 个元素有 ...
- codeforces 1167B Lost Numbers
传送门:https://codeforces.com/contest/1167/problem/B 题意: 交互题:现在你有6个数4, 8, 15, 16, 23, 42组成的某种组合,你可以询问系统 ...
- HTTPS RAS
这篇文章讲的清楚 https://zhuanlan.zhihu.com/p/75461564
- monorepo仓库管理方式探秘
前言 随着功能和业务量级的飙升,前端代码量级也越来越大,管理运维的成本也进一步增加. 代码仓库的运营管理挑战也浮出水面. 主流方案有两种:一是multirepo式的分散式的独立仓库,二是monorep ...
- JDBC 详解笔记
# JDBC ## 1:What? 通过Java代码来操作数据库的. 数据库的种类很多,导致不同的数据库的操作方式是不同. 通过JDBC的标准完成.通过java语言完成对于数据库的CRUD. ## 2 ...
- 【python小随笔】celery异步任务与调用返回值
s1.py(配置任务文件) from celery import Celery import time my_task = Celery("tasks", broker=" ...
- Serverless Kubernetes 入门:对 Kubernetes 做减法
作者 | 贤维 阿里巴巴高级技术专家 导读:Serverless Kubernetes 是阿里云容器服务团队对未来 Kubernetes 演进方向的一种探索,通过对 Kubernetes 做减法,降 ...
- 单用户登陆demo-后者挤到前者,类似QQ
单用户登陆demo ,采用的是Tp5. 流程是,当用户首次登陆是验证用户帐号密码,成功的,用当前时间戳加上用户id和ip 拼接成一个标识,暂且sign ,然后存入cookie ,时间戳存入缓存redi ...
- 《图解机器学习-杉山将著》读书笔记---CH3
CH3 最小二乘学习法 重点提炼 提出最小二乘学习法的缘故: 最小二乘学习法公式 对不同模型进行最小二乘法学习,得到最小二乘公式中的参数theta: 1.线性模型 代入3.1公式,对参数求偏导,偏 ...