luogu P4389 付公主的背包
神仙题鸭!orz dkw
暴力就是完全背包
而完全背包可以和生成函数扯上关系,记第i种物品质量为\(a_i\),那么这种物品的生成函数\(G(i)=\sum_{j=0}^{\infty}x^{a_ij}\),最后体积为i的答案即为这n个生成函数的卷积的第i项系数
然而用卷积复杂度为\(O(mnlogm)\),还不如暴力.说道卷积,我就想起了可以把多项式先求\(ln\),然后加起来,最后求\(exp\).只不过每个函数求\(ln\)复杂度还是不行,我们打表发现\(lnG(i)=\sum_{j=0}^{\infty}\frac{1}{j}x^{a_ij}\),所以直接把对应项的系数通过枚举倍数加好救星了,复杂度\(O(\sum_{i=1}^{m}\lfloor\frac{m}{i}\rfloor) \approx O(nlogn)\)
#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register
using namespace std;
const int N=270000+10,mod=998244353;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
il int fpow(int a,int b){int an=1;while(b){if(b&1) an=1ll*an*a%mod;a=1ll*a*a%mod,b>>=1;} return an;}
int rdr[N];
il void ntt(int *a,int n,bool op)
{
int l=0,x,y;
while((1<<l)<n) ++l;
for(int i=0;i<n;++i) rdr[i]=(rdr[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<n;++i) if(i<rdr[i]) swap(a[i],a[rdr[i]]);
for(int i=1;i<n;i<<=1)
{
int ww=fpow(op?3:332748118,(mod-1)/(i<<1));
for(int j=0;j<n;j+=i<<1)
for(int k=0,w=1;k<i;++k,w=1ll*w*ww%mod)
x=a[j+k],y=1ll*a[j+k+i]*w%mod,a[j+k]=(x+y)%mod,a[j+k+i]=(x-y+mod)%mod;
}
if(!op) for(int i=0,w=fpow(n,mod-2);i<n;++i) a[i]=1ll*a[i]*w%mod;
}
int p1[N],p2[N],p3[N],p4[N],p5[N],p6[N],inv[N];
il void polyder(int *a,int *b,int n)
{
for(int i=0;i<n-1;++i) b[i]=1ll*a[i+1]*(i+1)%mod;
b[n-1]=b[n]=0;
}
il void polying(int *a,int *b,int n)
{
for(int i=1;i<n;++i) b[i]=1ll*a[i-1]*inv[i]%mod;
b[0]=0;
}
il void polyinv(int *a,int *b,int n)
{
if(n==1){b[0]=fpow(a[0],mod-2);return;}
polyinv(a,b,n>>1);
for(int i=0;i<n;++i) p1[i]=a[i],p2[i]=b[i];
ntt(p1,n<<1,1),ntt(p2,n<<1,1);
for(int i=0;i<(n<<1);++i) p1[i]=1ll*p1[i]*p2[i]%mod*p2[i]%mod;
ntt(p1,n<<1,0);
for(int i=0;i<n;++i) b[i]=((b[i]+b[i])%mod-p1[i]+mod)%mod;
for(int i=0;i<(n<<1);++i) p1[i]=p2[i]=0;
}
il void polyln(int *a,int *b,int n)
{
polyder(a,p3,n),polyinv(a,p4,n);
ntt(p3,n<<1,1),ntt(p4,n<<1,1);
for(int i=0;i<(n<<1);++i) p3[i]=1ll*p3[i]*p4[i]%mod;
ntt(p3,n<<1,0);
polying(p3,b,n);
for(int i=0;i<(n<<1);++i) p3[i]=p4[i]=0;
}
il void polyexp(int *a,int *b,int n)
{
if(n==1){b[0]=1;return;}
polyexp(a,b,n>>1);
polyln(b,p5,n);
for(int i=0;i<n;++i) p5[i]=(mod-p5[i]+a[i])%mod,p6[i]=b[i];
p5[0]=(p5[0]+1)%mod;
ntt(p5,n<<1,1),ntt(p6,n<<1,1);
for(int i=0;i<(n<<1);++i) p5[i]=1ll*p5[i]*p6[i]%mod;
ntt(p5,n<<1,0);
for(int i=0;i<n;++i) b[i]=p5[i];
for(int i=0;i<(n<<1);++i) p5[i]=p6[i]=0;
}
int a[N],b[N],cn[N],n,m;
int main()
{
n=rd(),m=rd();
inv[0]=inv[1]=1;
for(int i=2;i<=m;++i) inv[i]=(mod-1ll*mod/i*inv[mod%i]%mod)%mod;
for(int i=1;i<=n;++i) ++cn[rd()];
for(int i=1;i<=m;++i)
{
if(!cn[i]) continue;
for(int j=1;i*j<=m;++j)
a[i*j]=(a[i*j]+1ll*cn[i]*inv[j]%mod)%mod;
}
int l=1;
while(l<m+1) l<<=1;
polyexp(a,b,l);
for(int i=1;i<=m;++i) printf("%d\n",b[i]);
return 0;
}
luogu P4389 付公主的背包的更多相关文章
- 洛谷 P4389 付公主的背包 解题报告
P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...
- 洛谷 P4389: 付公主的背包
题目传送门:洛谷 P4389. 题意简述: 有 \(n\) 个物品,每个物品都有无限多,第 \(i\) 个物品的体积为 \(v_i\)(\(v_i\le m\)). 问用这些物品恰好装满容量为 \(i ...
- 洛谷P4389 付公主的背包--生成函数+多项式
题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...
- [luogu 4389] 付公主的背包
题意:求一个较大的多重背包对于每个i的方案数,答案对998244353取模. 思路: 生成函数: 对于一个\(V\) 设: \(f(x) = \sum_{i=0}^{oo} x ^ {V * i} = ...
- P4389 付公主的背包
注意 初始化的时候要这样写 for(int i=1,x;i<=n;i++){ scanf("%d",&x); v[x]++; } for(int i=1;i<= ...
- 洛谷P4389 付公主的背包 [生成函数,NTT]
传送门 同样是回过头来发现不会做了,要加深一下记忆. 思路 只要听说过生成函数的人相信第一眼都可以想到生成函数. 所以我们要求 \[ ans=\prod \sum_n x^{nV}=\prod \fr ...
- [洛谷P4389]付公主的背包
题目大意:有$n(n\leqslant10^5)$种物品,第$i$个物品体积为$v_i$,都有$10^5$件.给定$m(m\leqslant10^5)$,对于$s\in [1,m]$,请你回答用这些商 ...
- LuoguP4389 付公主的背包【生成函数+多项式exp】
题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...
- luoguP4389 付公主的背包
luogu 显然这是个背包题 显然物品的数量是不用管的 所以考虑大小为\(v\)的物品可以装的体积用生成函数表示一下 \[ f(x)=\sum_{i=0}^{+\infty}x^{vi}=\frac{ ...
随机推荐
- 利用twilio进行手机短信验证
首先要注册 twilio 账号但是由于twilio人机验证用的是Goole所有注册需要FQ 完成后去免费获取15元使用 然后 pip install twilio 注册完成后会在个人首页显示你的免费金 ...
- plink:ped格式转换为bed格式
命令行如下: plink --file FILENAME --make-bed --out FILENAME 第一个FILENAME的后缀为.ped和.map,生成的第二个FILENAME的后缀为.b ...
- unittest的使用一
selenium: (1).firefox官方下载驱动geckodriver,windows:放在\python36或者是27的目录下 Mac: /usr/local/bin (2).firefox的 ...
- curl 出现错误的调试方法
private function httpGet($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, tru ...
- 使用perconna xtrabackup备份脚本
使用percona xtrabackup对两个数据库实例进行备份,备份的脚本如下所示: #!/bin/bash BASEDIR="/usr/local/mysql" BIN=&qu ...
- 基础教程:Mac 电脑小白应该了解哪些东西?
文章素材来源:知乎 文章收录于:风云社区(www.scoee.com),提供1700多款mac软件下载. 本文提供给那些从 PC 阵营初入 Mac 的同学而准备的,我们希望从硬件和软件.设计风格和使用 ...
- bzoj2938 AC自动机 + 拓扑排序找环
https://www.lydsy.com/JudgeOnline/problem.php?id=2938 题意:给出N个01病毒序列,询问是否存在一个无限长的串不存在病毒序列 正常来说,想要寻找一个 ...
- 被顶级学术期刊枪毙的p.Value到底是个什么鬼
总结一下,在我看来,p.Value仅仅是在,假设检验,这理论框架下,对于证据力度的一个测量.而且,我们不大可能推翻假设检验这个框架,似乎也不必要,因为,这个框架非常合理,有广泛的应用场景,有强大的生命 ...
- Python3 图片转字符画
https://www.shiyanlou.com/courses/370/labs/1191/document from PIL import Image import argparse ascii ...
- Redis分布式锁----乐观锁的实现,以秒杀系统为例
本文使用redis来实现乐观锁,并以秒杀系统为实例来讲解整个过程. 乐观锁 大多数是基于数据版本(version)的记录机制实现的.即为数据增加一个版本标识,在基于数据库表的版本解决方案中, ...