luogu


显然这是个背包题

显然物品的数量是不用管的

所以考虑大小为\(v\)的物品可以装的体积用生成函数表示一下

\[f(x)=\sum_{i=0}^{+\infty}x^{vi}=\frac{1}{1-x^v}\\
ans=\prod_{i=1}^{n}\frac{1}{1-x^{v_i}}
\]

然而这样直接乘起来复杂度是\(O(mn\ log\ n)\)

然后套路,左右套上\(ln\)就可以化乘为加

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

把\(ln\)拆开

\[ln\ \frac{1}{1-x^v}=\int \frac{vx^{v-1}}{1-x^{v}}dx\\
ln\ \frac{1}{1-x^v}=\int \sum_{i=1}^{+\infty}vx^{vi-1}dx\\
ln\ \frac{1}{1-x^v}=\sum_{i=1}^{+\infty}\frac{1}{i}x^{vi}
\]

然后再求个exp就可以了

但是我们这样预处理最坏还是可以到\(O(n^2)\),对于每个体积记个桶优化一下就可以了

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=5e5+10,mod=998244353,g=3,gi=332748118;
int n,k,v[maxn],f[maxn],a[maxn],b[maxn],c[maxn],h[maxn],w[maxn],s[maxn],r[maxn],inv[maxn];
int mul(int x,int y){return 1ll*x*y-1ll*x*y/mod*mod;}
int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int del(int x,int y){return x-y<0?x-y+mod:x-y;}
int mi(int a,int b){
int ans=1;while(b){if(b&1)ans=mul(ans,a);b>>=1,a=mul(a,a);}
return ans;
}
void ntt(int *a,int n,int f){
for(rg int i=0;i<n;i++)if(r[i]>i)swap(a[i],a[r[i]]);
for(rg int i=1;i<n;i<<=1){
int wn=mi(f?g:gi,(mod-1)/(i<<1));
for(rg int j=0;j<n;j+=i<<1){
int w=1;
for(rg int k=0;k<i;k++){
int x=a[j+k],y=mul(w,a[j+k+i]);
a[j+k]=add(x,y),a[j+k+i]=del(x,y),w=mul(w,wn);
}
}
}
if(f)return ;int inv=mi(n,mod-2);
for(rg int i=0;i<n;i++)a[i]=mul(a[i],inv);
}
void get_inv(int *a,int *b,int n){
if(n==1)return b[0]=mi(a[0],mod-2),void();
get_inv(a,b,(n+1)>>1);int m,len=0;
for(m=1;m<=n<<1;m<<=1)len++;
for(rg int i=0;i<m;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
for(rg int i=0;i<n;i++)c[i]=a[i];
for(rg int i=n;i<m;i++)c[i]=0;
ntt(c,m,1),ntt(b,m,1);
for(rg int i=0;i<m;i++)b[i]=del(mul(2,b[i]),mul(c[i],mul(b[i],b[i])));
ntt(b,m,0);
for(rg int i=n;i<m;i++)b[i]=0;
}
void get_ln(int *a,int *b,int n){
for(rg int i=0;i<n;i++)w[i]=mul(a[i+1],i+1);
get_inv(a,s,n);int m,len=0;
for(m=1;m<=n<<1;m<<=1)len++;
for(rg int i=0;i<m;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
ntt(w,m,1),ntt(s,m,1);
for(rg int i=0;i<m;i++)s[i]=mul(s[i],w[i]);
ntt(s,m,0);b[0]=0;
for(rg int i=0;i<m;i++)b[i+1]=mul(s[i],mi(i+1,mod-2)),s[i]=w[i]=0;
for(rg int i=n;i<m;i++)b[i]=0;
}
void get_exp(int *a,int *b,int n){
if(n==1)return b[0]=1,void();
get_exp(a,b,(n+1)>>1);get_ln(b,h,n);
for(rg int i=0;i<n;i++)h[i]=del(a[i],h[i]);h[0]=add(h[0],1);
int m,len=0;for(m=1;m<=n<<1;m<<=1)len++;
for(rg int i=0;i<m;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(len-1));
ntt(b,m,1),ntt(h,m,1);
for(rg int i=0;i<m;i++)b[i]=mul(b[i],h[i]);
ntt(b,m,0);
for(rg int i=n;i<m;i++)b[i]=0;
}
int main()
{
read(n),read(k);
for(rg int i=1,x;i<=n;i++)read(x),v[x]++;
for(rg int i=1;i<=k;i++)inv[i]=mi(i,mod-2);
for(rg int i=1;i<=k;i++)
if(v[i])for(rg int j=i;j<=k;j+=i)a[j]=add(a[j],mul(v[i],inv[j/i]));
k++;get_exp(a,f,k);
for(rg int i=1;i<k;i++)printf("%d\n",f[i]);
}

luoguP4389 付公主的背包的更多相关文章

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

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

  2. [题解] LuoguP4389 付公主的背包

    这个题太神辣- 暴力背包就能获得\(30\)分的好成绩...... \(60\)分不知道咋搞..... 所以直接看\(100\)分吧\(QwQ\) 用一点生成函数的套路,对于一个体积为\(v\)的物品 ...

  3. luoguP4389 付公主的背包 多项式exp

    %%%dkw 话说这是个论文题来着... 考虑生成函数\(OGF\) 对于价值为\(v\)的物品,由于有\(10^5\)的件数,可以看做无限个 那么,其生成函数为\(x^0 + x^{v} + x^{ ...

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

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

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

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

  6. luogu P4389 付公主的背包

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

  7. luogu4389 付公主的背包

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

  8. P3489 付公主的背包

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

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

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

随机推荐

  1. BEC listen and translation exercise 41

    Its advantages are that it can be used for outside activities So my recommendation I'm afraid would ...

  2. 关于ATML信号定义的理解-1

    1.XML中的类型标签: <xs:complexType>复合类型和<xs:simpleTyle>简单类型是数据结构类型,包含了各种类型的属性.可以被子类型继承,继承方式为&l ...

  3. popupTheme和theme

    popupTheme是指toolBar中弹出的menu的Theme. 那么,如果想让ToolBar的文字是白色,如果你设置Toolbar的Theme是 "ThemeOverlay.AppCo ...

  4. Hihocoder1662 : 查找三阶幻方([Offer收割]编程练习赛40)(暴力)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个N x M的矩阵,请你数一数其中有多少个3 x 3的子矩阵可以构成三阶幻方? 如果3 x 3的矩阵中每一行.每一列 ...

  5. HLSL学习笔记(一):基础

    http://www.cnblogs.com/rainstorm/archive/2013/05/04/3057444.html 前言 五一在家无事,于是学习了一下HLSL,基于XAN4.0的.学习完 ...

  6. [转]JavaScript文件操作(2)-FileReader

    在上篇文章中,我介绍了在JavaScript操作文件,重点讲了如何取得File对象. 这些对象包含的文件的元数据在上传或者拖放到浏览器中时可以获取到.有了文件当然接下来就是读取文件了. FileRea ...

  7. BZOJ1657:[USACO2006MAR]Mooo

    浅谈栈:https://www.cnblogs.com/AKMer/p/10278222.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?id ...

  8. POJ1958:Strange Towers of Hanoi

    我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html 题目传送门:http://poj.org/problem?id=1958 题目要我们求四柱 ...

  9. SQL SERVER 中的*=和=*

    一.* =和= * 是在sql server2000中左连接,右连接的用法相当于left join 和right join,现在sql2005和2008默认是不支持的,可以设置兼容2000或2008 ...

  10. TModJS:template

    ylbtech-TModJS: 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech. ...