P4389-付公主的背包【生成函数,多项式exp】
正题
题目链接:https://www.luogu.com.cn/problem/P4389
题目大意
\(n\)种物品,第\(i\)种大小为\(v_i\),数量无限。对于每个\(s\in[1,m]\)求刚好填满\(s\)容量的方案数。
\(1\leq n,m\leq 10^5\)
解题思路
统计和为一定值的方案数,好像可以生成函数做?
每种物品大小\(v\)有一个生成函数
\]
然后所有生成函数乘起来就好了,但这样是\(O(n^2\log n)\)的比暴力还慢...
乘起来比较慢,如果\(ln\)之后改成加法就好了,但是\(ln\)也是\(O(n)\)的。不过我们的式子比较特殊,对于\(ln\)之后求个导就会有神器的结果
\]
\]
然后在积分回去就是
\]
然后记录每个大小的物品出现了多少次,之后\(O(m\log m)\)加系数,然后再\(exp+\)求逆回去就好了。
时间复杂度\(O(n+m\log m)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=4e5+10,P=998244353;
ll n,c,l,r[N],f[N],v[N],inv[N];
ll t1[N],t2[N],t3[N],t4[N],t5[N],t6[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
void Glen(ll m){
n=1;while(n<=m)n<<=1;
for(ll i=0;i<n;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);
return;
}
void NTT(ll *f,ll op){
for(ll i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=n;p<<=1){
ll len=p>>1,tmp=power(3,(P-1)/p);
if(op==-1)tmp=power(tmp,P-2);
for(ll k=0;k<n;k+=p){
ll buf=1;
for(ll i=k;i<k+len;i++){
ll tt=f[i+len]*buf%P;
f[i+len]=(f[i]-tt+P)%P;
f[i]=(f[i]+tt)%P;
buf=buf*tmp%P;
}
}
}
if(op==-1){
ll inv=power(n,P-2);
for(ll i=0;i<n;i++)
f[i]=f[i]*inv%P;
}
return;
}
void GetInv(ll *f,ll *g,ll m){
if(m==1){g[0]=power(f[0],P-2);return;}
GetInv(f,g,m>>1);Glen(m);
for(ll i=0;i<m;i++)t1[i]=f[i],t2[i]=g[i];
NTT(t1,1);NTT(t2,1);
for(ll i=0;i<n;i++)
t1[i]=t1[i]*t2[i]%P*t2[i]%P;
NTT(t1,-1);
for(ll i=0;i<m;i++)g[i]=(g[i]*2-t1[i]+P)%P;
for(ll i=0;i<n;i++)t1[i]=t2[i]=0;
return;
}
void GetD(ll *f,ll *g,ll n){
for(ll i=0;i<n-1;i++)
g[i]=f[i+1]*(i+1)%P;
g[n-1]=0;return;
}
void GetJ(ll *f,ll *g,ll n){
for(ll i=n-1;i>0;i--)
g[i]=f[i-1]*power(i,P-2)%P;
g[0]=0;return;
}
void GetLn(ll *f,ll *g,ll m){
Glen(m);GetD(f,t3,n);GetInv(f,t4,n);
Glen(m);Glen(n);NTT(t3,1);NTT(t4,1);
for(ll i=0;i<n;i++)t3[i]=t3[i]*t4[i];
NTT(t3,-1);GetJ(t3,g,n);
for(ll i=0;i<n;i++)t3[i]=t4[i]=0;
return;
}
void GetExp(ll *f,ll *g,ll m){
if(m==1){g[0]=1;return;}
GetExp(f,g,m>>1);GetLn(g,t5,m);Glen(m);
for(ll i=0;i<m;i++)t6[i]=f[i];
for(ll i=m;i<n;i++)t5[i]=0;
NTT(t5,1);NTT(t6,1);NTT(g,1);
for(ll i=0;i<n;i++)g[i]=g[i]*(1-t5[i]+t6[i]+P)%P;
NTT(g,-1);for(ll i=m;i<n;i++)g[i]=0;
return;
}
signed main()
{
scanf("%lld%lld",&c,&l);inv[1]=1;
for(ll i=2;i<N;i++)
inv[i]=P-(P/i)*inv[P%i]%P;
for(ll i=1;i<=c;i++){
ll x;scanf("%lld",&x);
v[x]++;
}
Glen(l);
for(ll i=l;i>=1;i--){
ll w=v[i];v[i]=0;
for(ll j=i;j<n;j+=i)
(v[j]+=w*(P-inv[j/i])%P)%=P;
}
ll p=n;GetExp(v,f,n);
for(ll i=0;i<n;i++)v[i]=0;
GetInv(f,v,n);
for(ll i=1;i<=l;i++)
printf("%lld\n",v[i]);
return 0;
}
P4389-付公主的背包【生成函数,多项式exp】的更多相关文章
- 洛谷P4389 付公主的背包--生成函数+多项式
题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...
- 洛谷P4389 付公主的背包 [生成函数,NTT]
传送门 同样是回过头来发现不会做了,要加深一下记忆. 思路 只要听说过生成函数的人相信第一眼都可以想到生成函数. 所以我们要求 \[ ans=\prod \sum_n x^{nV}=\prod \fr ...
- 洛谷 P4389 付公主的背包 解题报告
P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...
- 洛谷 P4389: 付公主的背包
题目传送门:洛谷 P4389. 题意简述: 有 \(n\) 个物品,每个物品都有无限多,第 \(i\) 个物品的体积为 \(v_i\)(\(v_i\le m\)). 问用这些物品恰好装满容量为 \(i ...
- luogu P4389 付公主的背包
传送门 神仙题鸭!orz dkw 暴力就是完全背包 而完全背包可以和生成函数扯上关系,记第i种物品质量为\(a_i\),那么这种物品的生成函数\(G(i)=\sum_{j=0}^{\infty}x^{ ...
- [洛谷P4389]付公主的背包
题目大意:有$n(n\leqslant10^5)$种物品,第$i$个物品体积为$v_i$,都有$10^5$件.给定$m(m\leqslant10^5)$,对于$s\in [1,m]$,请你回答用这些商 ...
- P4389 付公主的背包
注意 初始化的时候要这样写 for(int i=1,x;i<=n;i++){ scanf("%d",&x); v[x]++; } for(int i=1;i<= ...
- LuoguP4389 付公主的背包【生成函数+多项式exp】
题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...
- Luogu4389 付公主的背包(生成函数+多项式exp)
显然构造出生成函数,对体积v的物品,生成函数为1+xv+x2v+……=1/(1-xv).将所有生成函数乘起来得到的多项式即为答案,设为F(x),即F(x)=1/∏(1-xvi).但这个多项式的项数是Σ ...
- LOJ6077「2017 山东一轮集训 Day7」逆序对 (生成函数+多项式exp?朴素DP!)
题面 给定 n , k n,k n,k ,求长度为 n n n 逆序对个数为 k k k 的排列个数,对 1 e 9 + 7 \rm1e9+7 1e9+7 取模. 1 ≤ n , k ≤ 100 ...
随机推荐
- 基于css的一些动画
最近因为期末复习周,博客更新鸽了很久,趁着考完试还记得这件事,把之前的大作业里出现过的css动画总结一下 页脚的联系方式图标 这个图片原型是一个静态图 动画效果如下 html <div clas ...
- spring学习日志二
一.spring依赖注入的方式 1.通过set方法来完成注入 <bean id="student" class="com.zhiyou100.xz.spring.S ...
- Qt 中事件与处理
一.事件与处理程序在运算过程中发生的一些事情:鼠标单击.键盘的按下...这些的事件的监控与处理在Qt中不是以信号的方式处理的.当这些事件发生时会调用QObject类中的功能函数(虚函数),所有的控件类 ...
- 【转】ps命令详解与使用
ps 概述 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态 ...
- Mybatis中多表联查,查询出来的字段出现重名,造成数据异常的解决方法!
在做一对多出现的问题,引发的思考:当数据库表中,主表的主键id和明细表的中的字段名相同时怎么办?Mybatis进行自动映射赋值的时候会不会出现异常? 注意:M ...
- servlet中servletContext的五大作用(四)
1. 获取web的上下文路径 2. 获取全局的参数 3. 作为域对象使用 4. 请求转发 5. 读取web项目的资源文件 package day10.about_serv ...
- reids在linux上的安装《四》
linux 安装redis 完整步骤 红色字体在我的Centos上没有设置,因为我设置了密码 安装: 1.获取redis资源 wget http://download.redis.io/release ...
- mysql8.0----mysqldump抛出:Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
问题:我尝试使用mysqldump时,得到以下错误: 复制 $> mysqldump --single-transaction --h -u user -p db > db.sql my ...
- BUUCTF-[CISCN2019 华东北赛区]Web2
BUUCTF-[CISCN2019 华东北赛区]Web2 看题 一个论坛,内容不错:) 可以投稿,点击投稿发现要注册,那就先注册登录.随便账号密码就行. 常规操作,扫一下站点,发现有admin.php ...
- JDK、JRE、JVM的基本介绍
一 .Java三大版本 JavaSE 标准版(桌面程序.控制台开发-) JavaWE 嵌入式开发(手机.家电-) JavaEE 企业开发(web端.服务器开发-) 二.JDK.JRE.JVM区别 JD ...