BZOJ5019[Snoi2017]遗失的答案——FWT+状压DP
题目描述
输入
输出
样例输入
5
1 2 3 4 5
样例输出
2
2
0
2
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<bitset>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int mod=1000000007;
const int inv=500000004;
bool vis[10010];
int prime[10010];
int cnt;
int G,L,Q;
int n,x;
int num;
int sum;
int mask;
int mx[10];
int pr[10];
int f[1<<16];
int g[1<<16];
int tmp[1<<16];
int p[1<<16];
int res[1<<16];
int pre[600][1<<16];
int suf[600][1<<16];
void find()
{
for(int i=2;i<=10000;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&prime[j]*i<=10000;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
break;
}
}
}
}
void FWT_OR(int *a,int len,int opt)
{
for(int k=2;k<=len;k<<=1)
{
int t=k>>1;
for(int i=0;i<len;i+=k)
{
for(int j=i;j<i+t;j++)
{
if(opt==1)
{
a[j+t]=(a[j+t]+a[j])%mod;
}
else
{
a[j+t]=(a[j+t]-a[j]+mod)%mod;
}
}
}
}
}
void FWT_AND(int *a,int len,int opt)
{
for(int k=2;k<=len;k<<=1)
{
int t=k>>1;
for(int i=0;i<len;i+=k)
{
for(int j=i;j<i+t;j++)
{
if(opt==1)
{
a[j]=(a[j]+a[j+t])%mod;
}
else
{
a[j]=(a[j]-a[j+t]+mod)%mod;
}
}
}
}
}
void take(int x)
{
for(int i=1;i<=cnt&&prime[i]*prime[i]<=x;i++)
{
if(x%prime[i]==0)
{
pr[++num]=prime[i];
while(x%prime[i]==0)
{
x/=prime[i];
mx[num]++;
}
}
}
if(x>1)
{
pr[++num]=x,mx[num]=1;
}
}
int quick(int x,int y)
{
int res=1;
while(y)
{
if(y&1)
{
res=1ll*res*x%mod;
}
y>>=1;
x=1ll*x*x%mod;
}
return res;
}
void dfs(int dep,int x,int S1,int S2)
{
if(dep>num)
{
res[S1|(S2<<num)]++;
return ;
}
for(int i=0;i<=mx[dep];i++)
{
dfs(dep+1,x,S1|((i==0)<<(dep-1)),S2|((i==mx[dep])<<(dep-1)));
if(1ll*x*pr[dep]>n)
{
return ;
}
x*=pr[dep];
}
}
void add(int &x,int y)
{
x+=y;
if(x>mod)
{
x-=mod;
}
}
int get(int x)
{
int S=0;
for(int i=1;i<=num;i++)
{
int ans=0;
while(x%pr[i]==0)
{
x/=pr[i],ans++;
}
if(!ans)
{
S|=1<<(i-1);
}
if(ans==mx[i])
{
S|=1<<(i-1+num);
}
}
return S;
}
int main()
{
scanf("%d%d%d%d",&n,&G,&L,&Q);
find();
if(L%G)
{
while(Q--)
{
puts("0");
}
return 0;
}
L/=G,n/=G;
take(L);
dfs(1,1,0,0);
mask=1<<(num+num);
for(int i=0;i<mask;i++)
{
if(res[i])
{
g[++sum]=i;
p[sum]=quick(2,res[i])-1;
}
}
f[0]=1,pre[0][0]=1;
for(int i=1;i<=sum;i++)
{
for(int j=0;j<mask;j++)
{
add(tmp[j|g[i]],1ll*f[j]*p[i]%mod);
}
for(int j=0;j<mask;j++)
{
add(f[j],tmp[j]),tmp[j]=0;
}
for(int j=0;j<mask;j++)
{
pre[i][j]=f[j];
}
}
memset(f,0,sizeof(f));
f[0]=1,suf[sum+1][0]=1;
for(int i=sum;i>=1;i--)
{
for(int j=0;j<mask;j++)
{
add(tmp[j|g[i]],1ll*f[j]*p[i]%mod);
}
for(int j=0;j<mask;j++)
{
add(f[j],tmp[j]),tmp[j]=0;
}
for(int j=0;j<mask;j++)
{
suf[i][j]=f[j];
}
}
for(int i=0;i<=sum;i++)
{
FWT_OR(pre[i],mask,1);
FWT_OR(suf[i+1],mask,1);
}
for(int i=0;i<sum;i++)
{
for(int j=0;j<mask;j++)
{
pre[i][j]=1ll*pre[i][j]*suf[i+2][j]%mod;
}
}
for(int i=0;i<sum;i++)
{
FWT_OR(pre[i],mask,-1);
FWT_AND(pre[i],mask,1);
}
while(Q--)
{
scanf("%d",&x);
if(x%G){puts("0");continue;}
x/=G;
if(L%x){puts("0");continue;}
if(x>n){puts("0");continue;}
int S=get(x);
int ans=0;
int y=lower_bound(g+1,g+1+sum,S)-g-1;
ans=pre[y][(mask-1)^S];
ans=1ll*ans*inv%mod*(p[y+1]+1)%mod;
printf("%d\n",ans);
}
}
BZOJ5019[Snoi2017]遗失的答案——FWT+状压DP的更多相关文章
- bzoj5019: [Snoi2017]遗失的答案
Description 小皮球在计算出答案之后,买了一堆皮肤,他心里很开心,但是一不小心,就忘记自己买了哪些皮肤了.==|||万 幸的是,他还记得他把所有皮肤按照1-N来编号,他买来的那些皮肤的编号( ...
- BZOJ5019 SNOI2017遗失的答案(容斥原理)
显然存在方案的数一定是L的因数,考虑对其因子预处理答案,O(1)回答. 考虑每个质因子,设其在g中有x个,l中有y个,则要求所有选中的数该质因子个数都在[x,y]中,且存在数的质因子个数为x.y.对于 ...
- 【BZOJ5019】[SNOI2017]遗失的答案(FWT,动态规划)
[BZOJ5019][SNOI2017]遗失的答案(FWT,动态规划) 题面 BZOJ 题解 发现\(10^8\)最多分解为不超过\(8\)个本质不同质数的乘积. 而\(gcd\)和\(lcm\)分别 ...
- Luogu4221 WC2018州区划分(状压dp+FWT)
合法条件为所有划分出的子图均不存在欧拉回路或不连通,也即至少存在一个度数为奇数的点或不连通.显然可以对每个点集预处理是否合法,然后就不用管这个奇怪的条件了. 考虑状压dp.设f[S]为S集合所有划分方 ...
- [WC2018]州区划分(状压DP+FWT/FMT)
很裸的子集反演模板题,套上一些莫名其妙的外衣. 先预处理每个集合是否合法,再作显然的状压DP.然后发现可以写成子集反演的形式,直接套模板即可. 子集反演可以看这里. 子集反演的过程就是多设一维代表集合 ...
- bzoj 5019 [Snoi2017]遗失的答案
题面 https://www.lydsy.com/JudgeOnline/problem.php?id=5019 题解 如果L不是G的倍数 答案为0 下面考虑G|L的情况 将G,L质因数分解 设$L= ...
- 洛谷$P5366\ [SNOI2017]$遗失的答案 数论+$dp$
正解:数论$dp$ 解题报告: 传送门$QwQ$ 考虑先质因数分解.所以$G$就相当于所有系数取$min$,$L$就相当于所有系数取$max$ 这时候考虑,因为数据范围是$1e8$,$1e8$内最多有 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
随机推荐
- 时间序列算法(平稳时间序列模型,AR(p),MA(q),ARMA(p,q)模型和非平稳时间序列模型,ARIMA(p,d,q)模型)的模型以及需要的概念基础学习笔记梳理
在做很多与时间序列有关的预测时,比如股票预测,餐厅菜品销量预测时常常会用到时间序列算法,之前在学习这方面的知识时发现这方面的知识讲解不多,所以自己对时间序列算法中的常用概念和模型进行梳理总结(但是为了 ...
- 利用 Blob 处理 node 层返回的二进制文件流字符串并下载文件
博客地址:https://ainyi.com/65 解释 | 背景 看到标题有点懵逼,哈哈,实际上是后端将文件处理成二进制流,返回到前端,前端处理这个二进制字符串,输出文件或下载 最近公司有个需求是用 ...
- Windows环境下安装配置Mosquitto服务及入门操作介绍
关键字:在windows安装mosquitto,在mosquitto中配置日志,在mosquitto中配置用户账号密码 关于Mosquitto配置的资料网上还是有几篇的,但是看来看去,基本上都是基于L ...
- 为 Eureka 服务注册中心实现安全控制
上一篇Eureka 实现微服务注册发现讲了用 Eureka 实现单体版的服务注册与发现.因为本篇是在上一篇的基础上的一点扩充,所以读此篇之前要保证看了上一篇. Eureka 如果不加安全控制,会存在下 ...
- mysql-8.0 安装教程(自定义配置文件,密码方式已修改)
下载zip安装包: MySQL8.0 For Windows zip包下载地址:https://dev.mysql.com/downloads/file/?id=476233,进入页面后可以不登录.后 ...
- 如何利用GitHub设计一个炫酷的个人网站(含代码)
1.在开始制作之前我们先预览一下我的网站吧! 1.方式一: 由于是手机版的所以用手机访问下面的链接体验比较好一点: https://tom-shushu.github.io/MyWeb.github. ...
- CSS 三条横线等分
.header_qian { width: 1.5rem; height: 1.5rem; background: rgba(250, 250, 250,0.7); border-radius: 50 ...
- arcgis api for js入门开发系列十九图层在线编辑
本篇主要讲述的是利用arcgis api实现图层在线编辑功能模块,效果图如下: 实现思路: 1.arcgis server发布的FeatureServer服务提供的图层在线编辑能力: 2.实现的在线编 ...
- Android远程桌面助手(B1332)之文件管理器
Android远程桌面助手除了支持Android界面的显示及控制外,还支持Android文件系统的管理,包括文件的快速上传(push).下拉(pull)和查看(cat). Android远程桌面助手( ...
- Arch LInux安装dde(Deepin Desktop Environment 深度桌面环境)
我一直比较推荐一些Linux新手使用Deepin Linux,因为我认为这种尽量的follow Windows的系统至少对于新手来说是比较的友好的,而且预装了QQ 火狐浏览器中文版,甚至还移植了像36 ...