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. codeforces 632A A. Grandma Laura and Apples(暴力)

    A. Grandma Laura and Apples time limit per test 1 second memory limit per test 256 megabytes input s ...

  2. leetcode 205. Isomorphic Strings(哈希表)

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  3. 基于DirectShow和FFmpeg的USB摄像头监控软件-转

    第一个版本 ### 软件版本及实现功能 0.0.1 1. USB摄像头枚举和设备信息获取2. 实时视频观看3. 24小时不间断录像,录像文件支持暴风影音播放 ### 软件说明: 软件基于 Direct ...

  4. 【转】 Pro Android学习笔记(三三):Menu(4):Alternative菜单

    目录(?)[-] 什么是Alternative menu替代菜单 小例子说明 Alternative menu代码 关于Category和规范代码写法 关于flags 多个匹配的itemId等参数 什 ...

  5. error: converting to execution character set: Invalid or incomplete multibyte or wide character

    交叉编译.c文件,遇到如下问题 arm-linux-gcc -o show_lines show_lines.c -lfreetype -lm show_lines.c:199:19: error: ...

  6. oracle--分页过程demo1

    oracle分页过程demo1: --ROWNUM用法 select o.*,rownum rn from (select * from emp) o where rownum<=10; sel ...

  7. java处理中日文字符串的乱码问题

    ——杂言:前段时间在处理音频预览问题,详见关于audiojs的研究.期间,将远端的音频下载并缓存在本地过程中,涉及到java.io.*的几个操作,发生一些乱码问题. 我以前的处理是将本地的编码转换为U ...

  8. Dialog 自定义使用2(进度条)

    1:  自定义的Dialog 代码: public class IphoneProgersssDialog extends Dialog { private Context context; priv ...

  9. Luogu 2258 [NOIP2014] 子矩阵

    被普及组虐了,感觉

  10. 8、泛型程序设计与c++标准模板库2.4列表容器

    列表容器主要用于存放链表,其中的链表是双向链表,可以从任意一端开始遍历.列表容器是需要按顺序访问的容器.另外,列表容器不支持随机访问迭代器,因此某些算法不能适合于列表容器.列表容器还提供了另一种操作- ...