BZOJ3462 DZY Loves Math II 【多重背包 + 组合数】
题目

输入格式
第一行,两个正整数 S 和 q,q 表示询问数量。
接下来 q 行,每行一个正整数 n。
输出格式
输出共 q 行,分别为每个询问的答案。
输入样例
30 3
9
29
1000000000000000000
输出样例
0
9
450000036
提示
对于100%的数据,2<=S<=2*106,1<=n<=1018,1<=q<=10^5
题解
DZY系列多神题
容易知道\(S\)所有质因子的指数最大为\(1\),否则结果都为\(0\)
如果满足,由\(S\)的范围可知其质因子最多有\(7\)个
那么\(n = \sum\limits_{i = 1}^{k} p_i * t_i\)
\(t_i\)表示第\(i\)个质因子选了几个
很像一个背包,但是\(n\)很大,考虑转化
我们先将\(n\)减去所有\(p_i\),保证至少选了一个
因为\(p_i\)是\(S\)的因子,所以可以写成\(p_i * t_i = Sx + p_iy\)且\([p_iy < S]\)
也就是分成若干个\(S\)和剩余不足\(S\)的部分
那么最终的\(n\)一定是由若干个前面部分的\(S\)和后面部分的\(p_iy\)相加而得
由于任意的\(p_iy < S\),所以\(\sum p_iy < k * S\),如果做背包,状态数为\(k^2 * S \approx 10^8\)
可以吧,做一个\(O(k * kS)\)的多重背包
看起来很汗,但可以跑过
至于这个多重背包的求法,就用一个类似滑动窗口的方法就可以实现\(O(k * kS)\)了
然后对于每个\(n\),枚举多出来的部分\(n \mod S + i * S\),\(0 \le i < 7\)
除了后面多出来的,前面的若干\(S\)要分配给那些质因子,用组合数挡板法即可
就可以\(O(7p)\)询问了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000,P = 1e9 + 7;
inline LL read(){
LL out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int f[15000000],g[15000000],inv[10];
int S,p[maxn],pi,sum;
LL N;
bool Sp(){
int x = S;
for (int i = 2; i * i <= x; i++)
if (x % i == 0){
int cnt = 0;
p[++pi] = i; sum += i;
while (x % i == 0) x /= i,cnt++;
if (cnt > 1) return true;
}
if (x - 1) p[++pi] = x,sum += x;
return false;
}
bool init(){
if (Sp()) return true;
f[0] = 1;
int M = pi * S;
for (int i = 1; i <= pi; i++){
memcpy(g,f,sizeof(f));
for (int j = 0; j < p[i]; j++)
{
LL w = 0;
for (int k = j; k <= M; k += p[i])
{
w = (w + g[k]) % P;
if (k - S >= 0) w = ((w - g[k - S]) % P + P) % P;
f[k] = w;
}
}
}
inv[0] = inv[1] = 1;
for (int i = 2; i < 10; i++) inv[i] = 1ll * (P - P / i) * inv[P % i] % P;
return false;
}
int cal(LL x,int y){
LL n = x + y - 1,m = y - 1;
int re = 1;
for (int i = 1; i <= m; i++)
re = 1ll * re * ((n - i + 1) % P) % P * inv[i] % P;
return re;
}
int main(){
S = read(); int T = read();
if (init()){
while (T--) puts("0");
return 0;
}
while (T--){
N = read();
N -= sum;
if (N < 0){puts("0"); continue;}
LL ans = 0,cnt = N / S;
for (int i = 0; i < pi && i <= cnt; i++)
ans = (ans + 1ll * f[N % S + i * S] * cal(cnt - i,pi) % P) % P;
printf("%lld\n",ans);
}
return 0;
}
BZOJ3462 DZY Loves Math II 【多重背包 + 组合数】的更多相关文章
- DZY Loves Math II:多重背包dp+组合数
Description Input 第一行,两个正整数 S 和 q,q 表示询问数量.接下来 q 行,每行一个正整数 n. Output 输出共 q 行,分别为每个询问的答案. Sample Inpu ...
- [bzoj3462]DZY Loves Math II (美妙数学+背包dp)
Description Input 第一行,两个正整数 S 和 q,q 表示询问数量. 接下来 q 行,每行一个正整数 n. Output 输出共 q 行,分别为每个询问的答案. Sample Inp ...
- BZOJ3462 DZY Loves Math II(动态规划+组合数学)
容易发现这是一个有各种玄妙性质的完全背包计数. 对于每个质数,将其选取个数写成ax+b的形式,其中x=S/pi,0<b<x.那么可以枚举b的部分提供了多少贡献,多重背包计算,a的部分直接组 ...
- bzoj3462: DZY Loves Math II
状态很差脑子不清醒了,柿子一直在推错.... ... 不难发现这个题实际上是一个完全背包 问题在于n太大了,相应的有质数的数量不会超过7个 假设要求sigema(1~plen)i pi*ci=n 的方 ...
- bzoj 3462: DZY Loves Math II
3462: DZY Loves Math II Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 211 Solved: 103[Submit][Sta ...
- DZY Loves Math II
简要题面 对于正整数 \(S, n\),求满足如下条件的素数数列 \((p_1,p_2,\cdots,p_k)\)(\(k\) 为任意正整数) 的个数: \(p_1\le p_2\le\cdots\l ...
- BZOJ 3462 DZY Loves Math II ——动态规划 组合数
好题. 首先发现$p$是互质的数. 然后我们要求$\sum_{i=1}^{k} pi*xi=n$的方案数. 然后由于$p$不相同,可以而$S$比较小,都是$S$的质因数 可以考虑围绕$S$进行动态规划 ...
- DZY Loves Math系列
link 好久没写数学题了,再这样下去吃枣药丸啊. 找一套应该还比较有意思的数学题来做. [bzoj3309]DZY Loves Math 简单推一下. \[\sum_{i=1}^n\sum_{j=1 ...
- [BZOJ] DZY Loves Math 系列 I && II
为了让自己看起来有点事干 ,做个套题吧..不然老是东翻翻西翻翻也不知道在干嘛... \(\bf 3309: DZY \ Loves \ Math\) 令 \(h=f*\mu\) 很明显题目要求的就是\ ...
随机推荐
- Softmax回归(Softmax Regression
多分类问题 在一个多分类问题中,因变量y有k个取值,即.例如在邮件分类问题中,我们要把邮件分为垃圾邮件.个人邮件.工作邮件3类,目标值y是一个有3个取值的离散值.这是一个多分类问题,二分类模型在这里不 ...
- 题解 CF656G 【You're a Professional】
又是一道假黑题 它教会我们不要看难度标签 虽然这道题的数据范围很小,用cin能过,但我还是要讲一下快读 快读嘛,顾名思义,就是 快速读入 的意思 有同学就会问了,快速读入的原理是什么? 答:它的原理其 ...
- Java代码工具箱之链接Oracle
1. 需要oracle的 odbc jar包 2. 代码 3. 注意:ps对象和statement对象最好用完立即释放,尤其是读写数据库代码出现在 for 循环语句中时. 否则会出现游标不够的情况, ...
- PL/SQL的安装
一.下载PLSQLDeveloper 网址:https://www.allroundautomations.com/bodyplsqldevreg.html 还需要一个激活码 二.PL/SQL的安装 ...
- Java十进制转成二进制 八进制 十六进制
int a = 357;//十进制转成二进制System.out.println(Integer.toBinaryString(a)); package com.swift; import java. ...
- 用PHP和Python生成短链接服务的字符串ID
假设你想做一个像微博短链接那样的短链接服务,短链接服务生成的URL都非常短例如: http://t.cn/E70Piib, 我们应该都能想到链接中的E70Piib对应的就是存储长链接地址的数据记录的I ...
- mysql索引详细描述与应用场景
索引的数据结构: (1)一般是B+tree:MySql使用最频繁的一个索引数据结构,数据结构以平衡树的形式来组织,因为是树型结构,所以更适合用来处理排序,范围查找等功能. (2)Hash:Hsah索引 ...
- Laravel — homestead 配置多站点
一.homestead.yaml 配置 homestead.yaml 文件配置sites,如下 sites: - map: homestead.test to: /home/vagrant/Code/ ...
- 第8课 Thinkphp 5 update判断修改成功与失败 Thinkphp5商城第四季
没有修改数据时,判断修改成功与失败 如果提交时的数据库里之前的数据一样(即没有修改就提交表单),会返回0,此时 判断修改成功用$save !== false 这样才会提示修改成功. $save=db( ...
- Python9-MySQL-MySQL存储过程-视图-触发器-函数-day45
视图:某个查询语句设置别名,日后方便使用 CREATE VIEW v1 as SELECT * FROM student WHERE sid >10 -创建: create view 视图名称 ...