Description

Input

第一行,两个正整数 S 和 q,q 表示询问数量。
接下来 q 行,每行一个正整数 n。

Output

输出共 q 行,分别为每个询问的答案。

Sample Input

30 3
9
29
1000000000000000000

Sample Output

0
9
450000036

Hint

感谢the Loser协助更正数据
对于100%的数据,2<=S<=2e6​​,1<=n<=101810^{18}10​18​​,1<=q<=10510^510​5​​

好题!

10%算法:

对于S为平方数的倍数时,输出T个0

证明:无论用什么素数去lcm,结果都不可能是平方数

20%算法:

对于输入的n,因为每个素数至少出现一次(否则lcm凑不到),所以需要改动

S数据规模可以看出,素数的数量不会超过7个,即背包的物品少于7个

我们只需要把n减去所有的素数,就相当于先把每个物品都选了一遍

剩下的就是普通背包,不再讲解。(需要结合上一个10%的算法)

100%算法:

n很大,S还可以,物品种数也很少,它们的lcm也在可接受范围之内。

我颓的唯一一句题解:

"n很大,我们考虑一种合法方案,每个ci都不小,而p又是s的约数,我们尝试给ci%=s/pi"

然后就像明白了,受了这个启发后就在自己能力范围之内了

想一下为什么要模,因为我们可以发现每当取的物品数到达s/pi时,那么总量就到达了s,对于每个物品都是这样

那么,对于n,可以把它划分成n=as+c,我们把凑满s的部分叫做一个块

每一个块都可能是被每一个素数凑成的,所以如果有a个块,那么只考虑这些块,总的方案数是多少?

比较容易想到挡板法,可是不太一样:

挡板法用于n个相同物品分成k组,每组至少一件,答案是C(n-1,k-1)

可是我们需要的是n物品k组,每一组至少0件,那么和从背包每个必装一种而使n减掉每种物品相似,我们把物品增加k件从而保证每组都有

那么就是C(n+k-1,k-1)了

至于组合数怎么算。。。因为k-1很小,暴力就好,处理出逆元,n+k-1那部分暴力乘

但是要注意,因为那个部分太大,在乘之前就要取一次模,不然爆LL

好的我们现在处理完了整块的部分,接下来来考虑零散部分(零散部分已不含整块)

显然零散部分没有整块的话它的大小不会很大,最多就是素数个数乘以lcm,1.4e7,可以接受,背包解决

但是,我们怎么保证每个物品都不会凑成一个整块呢?

那么就有了个数限制,它不再是完全背包,而是多重背包

怎么办?其实这么想就偏了

考虑对于dp[m],如果它已经含有整块了,那么去掉这个整块的部分有几种方案,减去不就好了么?

即dp[m]-=dp[m-s];那么就搞定了个数限制的问题,它还是个完全背包

 for(int j=;j<=cntp;++j){
for(int i=;i+p[j]<=maxn;++i)
if(bp[i])bp[i+p[j]]=(bp[i]+bp[i+p[j]])%mod;
for(int i=maxn;i>=;--i)
if(i+ss<=maxn)bp[i+ss]=(bp[i+ss]-bp[i]+mod)%mod;
}

背包部分代码

那么就没什么问题了,最后再说一句n=as+c的分解不是简单的取模,c那个部分可以大于s

因为用k个物品,每个物品的贡献都不到s,但是它们能凑出的最大值接近于ks

多枚举几轮就好啦

 /*
我颓了题解的第一句话,这题我水了
"n很大,我们考虑一种合法方案,每个ci都不小,而p又是s的约数,我们尝试给ci%=s/pi"
然后就不需要在往下看了。
*/
#include<cstdio>
#define mod 1000000007
#define int long long
int s,t,p[],cntp,bp[],maxn,tot,th[],bj[],ths,invv[],inv[];int n;
inline int max(int a,int b){return a>b?a:b;}
main(){
scanf("%lld%lld",&s,&t);int ss=s;
for(int i=;i*i<=s;++i)if(s%i==){
if(s/i%i==){
for(int i=;i<=t;++i)puts("");
return ;
}
p[++cntp]=i;s/=i;tot+=i;
}
if(s!=)p[++cntp]=s,tot+=s;maxn=cntp*ss;
bp[]=;
for(int j=;j<=cntp;++j){
for(int i=;i+p[j]<=maxn;++i)
if(bp[i])bp[i+p[j]]=(bp[i]+bp[i+p[j]])%mod;
for(int i=maxn;i>=;--i)
if(i+ss<=maxn)bp[i+ss]=(bp[i+ss]-bp[i]+mod)%mod;
}
inv[]=invv[]=inv[]=;for(int i=;i<=;++i)invv[i]=(mod+(-(mod/i)*invv[mod%i]%mod))%mod,inv[i]=inv[i-]*invv[i]%mod;
while(t--){
scanf("%lld",&n);n-=tot;
if(n<){puts("");continue;}
if(n<ss){printf("%lld\n",bp[n]);continue;}
int tms=n/ss,ans=;
for(int i=max(,tms-cntp+);i<=tms;++i){
int tans=inv[cntp-]*bp[n-i*ss]%mod;
for(int j=;j<cntp-;++j)tans=tans*((i-+cntp-j)%mod)%mod;
ans=(ans+tans)%mod;
}
printf("%lld\n",ans);
}
}

Finally Accept

DZY Loves Math II:多重背包dp+组合数的更多相关文章

  1. bzoj 3462: DZY Loves Math II

    3462: DZY Loves Math II Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 211  Solved: 103[Submit][Sta ...

  2. BZOJ3462 DZY Loves Math II 【多重背包 + 组合数】

    题目 输入格式 第一行,两个正整数 S 和 q,q 表示询问数量. 接下来 q 行,每行一个正整数 n. 输出格式 输出共 q 行,分别为每个询问的答案. 输入样例 30 3 9 29 1000000 ...

  3. [bzoj3462]DZY Loves Math II (美妙数学+背包dp)

    Description Input 第一行,两个正整数 S 和 q,q 表示询问数量. 接下来 q 行,每行一个正整数 n. Output 输出共 q 行,分别为每个询问的答案. Sample Inp ...

  4. BZOJ3462 DZY Loves Math II(动态规划+组合数学)

    容易发现这是一个有各种玄妙性质的完全背包计数. 对于每个质数,将其选取个数写成ax+b的形式,其中x=S/pi,0<b<x.那么可以枚举b的部分提供了多少贡献,多重背包计算,a的部分直接组 ...

  5. DZY Loves Math II

    简要题面 对于正整数 \(S, n\),求满足如下条件的素数数列 \((p_1,p_2,\cdots,p_k)\)(\(k\) 为任意正整数) 的个数: \(p_1\le p_2\le\cdots\l ...

  6. BZOJ 3462 DZY Loves Math II ——动态规划 组合数

    好题. 首先发现$p$是互质的数. 然后我们要求$\sum_{i=1}^{k} pi*xi=n$的方案数. 然后由于$p$不相同,可以而$S$比较小,都是$S$的质因数 可以考虑围绕$S$进行动态规划 ...

  7. bzoj3462: DZY Loves Math II

    状态很差脑子不清醒了,柿子一直在推错.... ... 不难发现这个题实际上是一个完全背包 问题在于n太大了,相应的有质数的数量不会超过7个 假设要求sigema(1~plen)i pi*ci=n 的方 ...

  8. [BZOJ] DZY Loves Math 系列 I && II

    为了让自己看起来有点事干 ,做个套题吧..不然老是东翻翻西翻翻也不知道在干嘛... \(\bf 3309: DZY \ Loves \ Math\) 令 \(h=f*\mu\) 很明显题目要求的就是\ ...

  9. DZY Loves Math系列

    link 好久没写数学题了,再这样下去吃枣药丸啊. 找一套应该还比较有意思的数学题来做. [bzoj3309]DZY Loves Math 简单推一下. \[\sum_{i=1}^n\sum_{j=1 ...

随机推荐

  1. 【MySQL】mysql5.7数据库的安装和配置

    第一步:直接从官网下载安装包,.msi 可以直接点击安装..zip直接解压到目录,本人是C:\Program Files\MySQL\mysql-5.7 第二步:需要配置环境变量,我的电脑->属 ...

  2. Flask学习之旅--Flask项目部署

    一.写在前面 Flask 作为一个轻量级的 Web 框架,具有诸多优点,灵活方便,扩展性强,开发文档也很丰富.在开发调试的过程中,我们往往会使用 Flask 自带的 Web 服务器,但如果要投入到生产 ...

  3. 数据表管理admin

    知识预览 admin组件使用 admin源码解析 回到顶部 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理工具是 django.contrib 的一部分.你 ...

  4. SQL 存储过程示例讲解

    create proc score_result ) --参数 as declare --定义变量@courseNo int, @testTime1 datetime, @avg int begin ...

  5. AlexNet网络

    AlexNet 中包含了比较新的技术点,首次在CNN中成功应用了 ReLu .Dropout和LRN等Trick. 1.成功使用了Relu作为CNN的激活函数,并验证其效果在较深的网络中超过了Sigm ...

  6. Fiddle弱网测试

    1.打开Fiddler,Rules->Performance->勾选 Simulate Modem Speeds,勾选之后访问网站会发现网络慢了很多: 接下来给大家解释一下这些个都是什么意 ...

  7. How to Compute The Derivatives (如何求导数)(TBC)

    A video by 3Blue1Brown in Bilibili\text{A video by 3Blue1Brown in Bilibili}A video by 3Blue1Brown in ...

  8. linux下 Mysql 安装使用

    .安装mysql sudo apt-get install mysql-server mysql-client sudo service mysql restart 2.5.7版本以上修修改updat ...

  9. postman-windows下newman的使用

    一.newman的安装 1.安装node.js下载https://nodejs.org/en/ C:\Users\iphauser>node -vv10.16.1C:\Users\iphause ...

  10. 百万年薪python之路 -- 内置函数练习

    1.整理今天笔记,课上代码最少敲3遍. 2.用列表推导式做下列小题 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 lst = [["a","b"],[ ...