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]);
}

最新文章

  1. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)
  2. Win32 OpenGL标准例子
  3. lumia 520无法开机
  4. OMNET++工具的使用(2)
  5. opengl&amp; 颜色
  6. [团队项目]sprint3 &amp; 团队贡献分。
  7. UVa(247),Floyd做传递闭包
  8. Bochs使用说明
  9. HDU 5387 Clock
  10. strut2服务器与android交互数据
  11. 物体自由落体动态模拟(Linear Subspace)
  12. Objective-C数据结构
  13. javascript 之 面向对象【创建对象】
  14. 细说shiro之七:缓存
  15. Maven中classifier
  16. PAT 1073 多选题常见计分法(20)(代码+思路)
  17. m3u8 player
  18. Linux下安装系统清理软件 BleachBit 1.4
  19. 事件绑定的快捷方式 利on进行事件绑定的几种情况
  20. windows删除或修改本地Git保存的账号密码

热门文章

  1. FFMPEG相关开源项目
  2. ACM学习历程—HDU5490 Simple Matrix (数学 &amp;&amp; 逆元 &amp;&amp; 快速幂) (2015合肥网赛07)
  3. WSGI服务与django的关系
  4. Unity Webplayer installation error- Unity Webplayer update finished, but installed..
  5. BZOJ1707:[Usaco2007 Nov]tanning分配防晒霜
  6. poj 2187 Beauty Contest —— 旋转卡壳
  7. centos7添加环境变量
  8. js中的setInterval
  9. C#图片压缩类winform
  10. JS ES6 -- let命令