题目

退役前抄一道生成函数快乐一下

就是让我们做一个完全背包,但是朴素的做法显然是\(O(nm)\)的

把每一个物品搞成一个多项式,显然这个多项式所有\(v_i\)的倍数箱为\(1\),剩下的为\(0\)

我们写成生成函数的话就是\(\frac{1}{1-x^{v_i}}\)

也就是我们我们要求的答案就是

\[\prod_{i=1}^n\frac{1}{1-x^{v_i}}
\]

直接大力卷积是 \(O(nmlogn)\)的,好像还比暴力慢了一点

发现连乘并不是很好处理,考虑取一个\(\ln\)

变成

\[e^{\sum_{i=1}^n\ln(\frac{1}{1-x^{v_i}})}
\]

也就是我们求出\(\sum_{i=1}^n\ln(\frac{1}{1-x^{v_i}})\)之后\(\exp\)回去就好了

考虑一下这个东西怎么求,先背一下定理\(\ln(\frac{1}{1-x^k})=\sum_{i=0}^{\infty}\frac{1}{i}x^{ki}\)

证明一下

\[\begin{aligned} \ln(\frac{1}{1-x^k})&=\int (1-x^k)(\frac{1}{1-x^k})'dx\\&=\int (1-x^k)\sum_{i=1}^{\infty}ki\times x^{ki-1}dx\\&=\int (\sum_{i=1}^{\infty}ki\times x^{ki-1}-\sum_{i=1}^{\infty}ki\times x^{ki-1}\times x^k)dx\\&=\int (\sum_{i=1}^{\infty}ki\times x^{ki-1}-\sum_{i=1}^{\infty}k(i-1)\times x^{ki-1})dx\\&=\int \sum_{i=1}^{\infty} kx^{ki-1}dx\\&=\sum_{i=0}^{\infty}\frac{1}{i}x^{ki}\end{aligned}
\]

于是我们调和级数搞一下\(\sum_{i=1}^n\ln(\frac{1}{1-x^{v_i}})\)之后\(\exp\)就好了

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=262144+5;
const int mod=998244353;
const int G[2]={3,(mod+1)/3};
int n,m,len;
int K[maxn],g[maxn],T[maxn],C[maxn],rev[maxn],inv[maxn],a[maxn],b[maxn],tax[maxn];
inline int ksm(int a,int b) {
int S=1;
while(b) {if(b&1) S=1ll*S*a%mod;b>>=1;a=1ll*a*a%mod;}
return S;
}
inline void NTT(int *f,int o) {
for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
for(re int i=2;i<=len;i<<=1) {
int ln=i>>1,og1=ksm(G[o],(mod-1)/i);
for(re int l=0;l<len;l+=i) {
int t,og=1;
for(re int x=l;x<l+ln;++x) {
t=1ll*og*f[x+ln]%mod;
f[x+ln]=(f[x]-t+mod)%mod;
f[x]=(f[x]+t)%mod;
og=1ll*og*og1%mod;
}
}
}
if(!o) return;
int Inv=inv[len];
for(re int i=0;i<len;i++) f[i]=1ll*f[i]*Inv%mod;
}
void Inv(int n,int *A,int *B) {
if(n==1) {B[0]=ksm(A[0],mod-2);return;}
Inv((n+1)>>1,A,B);
len=1;while(len<n+n) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
for(re int i=0;i<n;i++) g[i]=A[i];
for(re int i=n;i<len;i++) g[i]=0;
NTT(g,0),NTT(B,0);
for(re int i=0;i<len;i++) B[i]=(2ll*B[i]-1ll*g[i]*B[i]%mod*B[i]%mod+mod)%mod;
NTT(B,1);for(re int i=n;i<len;i++) B[i]=0;
}
void Ln(int n,int *A,int *B) {
memset(C,0,sizeof(C)),memset(T,0,sizeof(T));memset(B,0,sizeof(B));
for(re int i=1;i<n;i++) T[i-1]=1ll*i*A[i]%mod;
Inv(n,A,C);len=1;while(len<n+n) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
NTT(C,0),NTT(T,0);
for(re int i=0;i<len;i++) C[i]=1ll*C[i]*T[i]%mod;
NTT(C,1);for(re int i=1;i<n;i++) B[i]=1ll*C[i-1]*inv[i]%mod;
}
void Exp(int n,int *A,int *B) {
if(n==1) {B[0]=1;return;}
Exp((n+1)>>1,A,B);Ln(n,B,K);
len=1;while(len<n+n) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
for(re int i=0;i<n;i++) K[i]=(A[i]-K[i]+mod)%mod;
for(re int i=n;i<len;i++) K[i]=0;K[0]++;
NTT(B,0);NTT(K,0);
for(re int i=0;i<len;i++) B[i]=1ll*B[i]*K[i]%mod;
NTT(B,1);for(re int i=n;i<len;i++) B[i]=0;
}
int main() {
inv[1]=1;
for(re int i=2;i<maxn;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
n=read(),m=read()+1;
for(re int i=1;i<=n;i++) tax[read()]++;
for(re int i=1;i<=m;i++) {
if(!tax[i]) continue;
for(re int j=1;j*i<=m;j++)
a[j*i]=(a[j*i]+1ll*inv[j]*tax[i]%mod)%mod;
}
Exp(m,a,b);
for(re int i=1;i<m;i++) printf("%d\n",b[i]);
return 0;
}

【LGP4389】付公主的背包的更多相关文章

  1. 洛谷 P4389 付公主的背包 解题报告

    P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...

  2. LuoguP4389 付公主的背包【生成函数+多项式exp】

    题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...

  3. 洛谷P4389 付公主的背包--生成函数+多项式

    题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...

  4. luogu P4389 付公主的背包

    传送门 神仙题鸭!orz dkw 暴力就是完全背包 而完全背包可以和生成函数扯上关系,记第i种物品质量为\(a_i\),那么这种物品的生成函数\(G(i)=\sum_{j=0}^{\infty}x^{ ...

  5. luogu4389 付公主的背包

    题目链接:洛谷 题目大意:现在有$n$个物品,每种物品体积为$v_i$,对任意$s\in [1,m]$,求背包恰好装$s$体积的方案数(完全背包问题). 数据范围:$n,m\leq 10^5$ 这道题 ...

  6. P3489 付公主的背包

    题意:n<=1e5,m<=1e5,跑n个物品1到m容量的完全背包. 考虑暴力的做法就是把一些1/(1+x^a)的多项式乘起来即可. 考虑优化,取一下ln,转化为加法,然后exp回去就好了.

  7. 洛谷 P4389: 付公主的背包

    题目传送门:洛谷 P4389. 题意简述: 有 \(n\) 个物品,每个物品都有无限多,第 \(i\) 个物品的体积为 \(v_i\)(\(v_i\le m\)). 问用这些物品恰好装满容量为 \(i ...

  8. [luogu4389]付公主的背包(多项式exp)

    完全背包方案计数问题的FFT优化.首先写成生成函数的形式:对重量为V的背包,它的生成函数为$\sum\limits_{i=0}^{+\infty}x^{Vi}=\frac{1}{1-x^{V}}$于是 ...

  9. luoguP4389 付公主的背包

    luogu 显然这是个背包题 显然物品的数量是不用管的 所以考虑大小为\(v\)的物品可以装的体积用生成函数表示一下 \[ f(x)=\sum_{i=0}^{+\infty}x^{vi}=\frac{ ...

随机推荐

  1. Spark SQL设计

  2. (上线时清缓存)laravel 5.1 的程序性能优化(配置文件) - 简书

    代码上到正式环境后执行这六步 php artisan config:clear php artisan config:cache php artisan route:clear php artisan ...

  3. SQL Server - SQL Server/ bcp 工具如何通信

    问题-BCP通讯 ref: https://stackoverflow.com/questions/40664708/bcp-cannot-connect-to-aws-sql-server-but- ...

  4. [JZOJ3320] 【BOI2013】文本编辑器

    题目 题目大意 给你一个文本,要删去其中所有的'e'. 有三种操作: h光标左移. x删除光标上面的字母(光标是横着的). fc跳到后面的第一个字符为'c'的位置. 问操作序列的最短长度. 思考历程 ...

  5. 第十一篇:一点一滴学ibatis(一)

    一.常见ORM框架1.原生的JDBC.自己写的JDBC,基本上就只够程序跑起来,缺陷和漏洞一堆堆.回顾下jdbc的几个操作,加载驱动,建立连接,预处理语句,执行,结果集遍历.这个过程中,因为连接Con ...

  6. git撤销修改及版本回退

    场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file. 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步, ...

  7. uoj#311 【UNR #2】积劳成疾

    题目 考虑直接顺着从\(1\)填数填到\(n\)发现这是在胡扯 所以考虑一些奇诡的东西,譬如最后的答案长什么样子 显然某一种方案的贡献是一个\(\prod_{i=1}^nw_i^{t_i}\)状物,\ ...

  8. (十一)Json文件配置

    接上一节,新建一个项目:JsonConfigSample 依然添加Microsoft.AspNetCore.All 在项目下新建一个Class.json配置文件 { ", "Cla ...

  9. CAS机制详解

    目录 1. 定义 2. 实现原理 3. 无版本号CAS实战说明 4. CAS机制在Java中的应用 5. CAS的缺点 1. CPU开销过大 2. 不能保证代码块的原子性 3. ABA问题 6. JA ...

  10. 使用openSUSE Leap 42.2小记

    闪存记录 在2017年04月10日开始想用openSuSE. 2017年04月10日开始找资料制作U盘安装openSUSE. 是在windows 7中用imageWrite.exe 软件制作的.安装的 ...