P4389 付公主的背包

题目背景

付公主有一个可爱的背包qwq

题目描述

这个背包最多可以装\(10^5\)大小的东西

付公主有\(n\)种商品,她要准备出摊了

每种商品体积为\(V_i\),都有\(10^5\)件

给定\(m\),对于\(s\in [1,m]\),请你回答用这些商品恰好装\(s\)体积的方案数

输入输出格式

输入格式:

第一行\(n,m\)

第二行\(V_1\sim V_n\)

输出格式:

\(m\)行,第\(i\)行代表\(s=i\)时方案数,对\(998244353\)取模

说明

对于\(30\%\)的数据,\(n\le 3000,m\le 3000\)

对于\(60\%\)的数据,纯随机生成

对于\(100\%\)的数据, \(n\le 100000,m\le 100000\)

对于\(100\%\)的数据,\(V_i\le m\)


先构造一波生成函数

\[F_k(x)=\sum_{i=0}^{\infty}x^{iv_k}=\frac{1}{1-x^{v_k}}
\]

然后答案是\(n\)个东西卷起来,复杂度高达\(O(nm\log m)\),显然苟不住

不妨把\(n\)个函数都取对数,然后就成了多项式加法,可以直接枚举倍数做到\(O(m\ln m)\),现在考虑如何转换成为对数

\[\begin{aligned}
G&=\ln F\\
G'&=\frac{F'}{F}\\
&=(1-x^v)\sum_{i=0}^\infty vix^{vi-1}\\
&=\sum_{i=0}^\infty vix^{vi-1}-\sum_{i=0}^\infty vix^{v(i+1)-1}\\
&=\sum_{i=0}^\infty vix^{vi-1}-\sum_{i=0}^\infty v(i-1)x^{vi-1}\\
&=\sum_{i=0}^\infty vix^{vi-1}\\
G&=\int G'\\
&=\sum_{i=0}^\infty \frac{1}{i}x^{vi}
\end{aligned}
\]

于是我们需要实现的就只有多项式exp啦


Code:

#include <cstdio>
#include <algorithm>
const int N=(1<<18)+10;
const int mod=998244353,Gi=332748118;
#define mul(a,b) (1ll*(a)*(b)%mod)
#define add(a,b) ((a+b)%mod)
int ans[N],G[N],turn[N],ina[N],inb[N],lna[N],lnb[N],exa[N],exb[N],cnt[N],Inv[N];
int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;}
void NTT(int *a,int typ,int len)
{
int L=-1;for(int i=1;i<len;i<<=1) ++L;
for(int i=0;i<len;i++)
{
turn[i]=turn[i>>1]>>1|(i&1)<<L;
if(i<turn[i]) std::swap(a[i],a[turn[i]]);
}
for(int le=1;le<len;le<<=1)
{
int wn=qp(typ?3:Gi,(mod-1)/(le<<1));
for(int p=0;p<len;p+=le<<1)
{
int w=1;
for(int i=p;i<p+le;i++,w=mul(w,wn))
{
int tx=a[i],ty=mul(w,a[i+le]);
a[i]=add(tx,ty);
a[i+le]=add(tx,mod-ty);
}
}
}
if(!typ)
{
int inv=qp(len,mod-2);
for(int i=0;i<len;i++) a[i]=mul(a[i],inv);
}
}
void polyinv(int *a,int *b,int len)
{
if(len==1){b[0]=qp(a[0],mod-2);return;}
polyinv(a,b,len>>1);
for(int i=0;i<len<<1;i++) ina[i]=inb[i]=0;
for(int i=0;i<len;i++) ina[i]=b[i],inb[i]=a[i];
NTT(ina,1,len<<1),NTT(inb,1,len<<1);
for(int i=0;i<len<<1;i++) ina[i]=mul(ina[i],add(2,mod-mul(ina[i],inb[i])));
NTT(ina,0,len<<1);
for(int i=0;i<len;i++) b[i]=ina[i];
}
void inter(int *a,int n){for(int i=n;i;i--)a[i]=mul(a[i-1],Inv[i]);a[0]=0;}
void drev(int *a,int n){for(int i=0;i<n;i++)a[i]=mul(a[i+1],i+1);a[n]=0;}
void polyln(int *a,int *b,int len)
{
for(int i=0;i<len<<1;i++) lna[i]=lnb[i]=0;
for(int i=0;i<len;i++) lna[i]=a[i];
polyinv(lna,lnb,len);
drev(lna,len-1);
NTT(lna,1,len<<1),NTT(lnb,1,len<<1);
for(int i=0;i<len<<1;i++) lna[i]=mul(lna[i],lnb[i]);
NTT(lna,0,len<<1);
inter(lna,len-1);
for(int i=0;i<len;i++) b[i]=lna[i];
}
void polyexp(int *a,int *b,int len)
{
if(len==1){b[0]=1;return;}
polyexp(a,b,len>>1);
for(int i=0;i<len<<1;i++) exa[i]=exb[i]=0;
polyln(b,exa,len);
for(int i=0;i<len;i++) exa[i]=add(a[i]+(i==0),mod-exa[i]);
for(int i=0;i<len;i++) exb[i]=b[i];
NTT(exa,1,len<<1),NTT(exb,1,len<<1);
for(int i=0;i<len<<1;i++) exa[i]=mul(exa[i],exb[i]);
NTT(exa,0,len<<1);
for(int i=0;i<len;i++) b[i]=exa[i];
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
for(int v,i=1;i<=n;i++) scanf("%d",&v),++cnt[v];
++m;int len=1;while(len<m) len<<=1;
Inv[0]=1;for(int i=1;i<=len;i++) Inv[i]=qp(i,mod-2);
for(int i=1;i<=m;i++)
for(int j=i;j<=m;j+=i)
G[j]=add(G[j],mul(cnt[i],Inv[j/i]));
polyexp(G,ans,len);
for(int i=1;i<m;i++) printf("%d\n",ans[i]);
return 0;
}

2018.12.29

洛谷 P4389 付公主的背包 解题报告的更多相关文章

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

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

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

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

  3. 洛谷P4389 付公主的背包 [生成函数,NTT]

    传送门 同样是回过头来发现不会做了,要加深一下记忆. 思路 只要听说过生成函数的人相信第一眼都可以想到生成函数. 所以我们要求 \[ ans=\prod \sum_n x^{nV}=\prod \fr ...

  4. [洛谷P4389]付公主的背包

    题目大意:有$n(n\leqslant10^5)$种物品,第$i$个物品体积为$v_i$,都有$10^5$件.给定$m(m\leqslant10^5)$,对于$s\in [1,m]$,请你回答用这些商 ...

  5. 洛谷 4389 付公主的背包——多项式求ln、exp

    题目:https://www.luogu.org/problemnew/show/P4389 关于泰勒展开: https://blog.csdn.net/SoHardToNamed/article/d ...

  6. 洛谷 P4495 [HAOI2018]奇怪的背包 解题报告

    P4495 [HAOI2018]奇怪的背包 题目描述 小\(C\)非常擅长背包问题,他有一个奇怪的背包,这个背包有一个参数\(P\),当他 向这个背包内放入若干个物品后,背包的重量是物品总体积对\(P ...

  7. 洛谷 P2323 [HNOI2006]公路修建问题 解题报告

    P2323 [HNOI2006]公路修建问题 题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 思路: 二分答案 然后把每条能加的大边都加上,然后加小边 但在洛谷的题 ...

  8. luogu P4389 付公主的背包

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

  9. P4389 付公主的背包

    注意 初始化的时候要这样写 for(int i=1,x;i<=n;i++){ scanf("%d",&x); v[x]++; } for(int i=1;i<= ...

随机推荐

  1. 20155223 Exp6 信息收集与漏洞扫描

    20155223 Exp6 信息收集与漏洞扫描 本次实验以熟悉信息收集手段与漏洞扫描手段为主. 实践步骤 whois域名查找 在虚拟机Kali的终端输入命令:whois baidu.com,查询百度的 ...

  2. TKmath Package gp数据类型

    点,向量,方向 二维:gp_Pnt2d, gp_Vec2d, gp_Dir2d:它们的内部都存储 gp_XY 三维:gp_Pnt, gp_Vec, gp_Dir:它们的内部都存储 gp_XYZ 轴向与 ...

  3. App云测试服务对比

    前言: 我们都知道在测试移动app时最耗时的是在各种测试设备进行测试, 因为不论是安卓还是iOS都已经碎片化了.而云测试看似是解决这一问题的有效途径.因此选择哪种云测试平台来协助测试人员进行各种测试就 ...

  4. PAT-1045. Favorite Color Stripe (30)-LIS

    将Eva喜欢的颜色按顺序编个优先级, 2 3 1 5 6-> 1 2 3 4 5 然后读取stripe,将Eva不喜欢的先剔除掉,剩下的颜色替换为相应的优先级 2 2 4(去掉) 1 5 5 6 ...

  5. .net中操作Visual SourceSafe

    最近整理一些资料,发现以前写的一段代码,提供对微软的版本管理软件visual sourcesafe的一些操作.以下简称vss. 想起以前写的时候,因为资料比较匮乏,只能边研究边测试,走了不少弯路. 由 ...

  6. 《Linux内核分析》--扒开系统调用的三层皮 20135311傅冬菁

    扒开系统调用的三层皮           20135311傅冬菁 一.内容分析 寄存器上下文(从用户态切换到内核态) 中断/int指令会在堆栈上保存一些寄存器的值(用户态栈顶地址..当时的状态字.当下 ...

  7. 小学四则运算APP 第一个冲刺阶段 第一天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第一次冲刺阶段时间:11.17~11.27 思考:初步了解小学四则运算数是在100以内的加减乘除,首先先从简单的地方入手,把最基础的算法功 ...

  8. Beta阶段冲刺-3

    一. 每日会议 1. 照片 2. 昨日完成工作 3. 今日完成工作 4. 工作中遇到的困难 杨晨露:组内图表部分遇到了问题,他们的问题一出来,我就头疼了......因为要调整计划时间,所以我觉得我的困 ...

  9. Beta版本冲刺(六)

    目录 组员情况 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内最新成果 团队签入记 ...

  10. ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度

    ElasticSearch 2 (24) - 语言处理系列之停用词:性能与精度 摘要 在信息检索早期,磁盘和内存相较我们今天的使用只是很小的一部分.将索引空间保持在一个较小的水平是至关重要的,节省每个 ...