luoguP4389 付公主的背包
luogu
显然这是个背包题
显然物品的数量是不用管的
所以考虑大小为\(v\)的物品可以装的体积用生成函数表示一下
ans=\prod_{i=1}^{n}\frac{1}{1-x^{v_i}}
\]
然而这样直接乘起来复杂度是\(O(mn\ log\ n)\)
然后套路,左右套上\(ln\)就可以化乘为加
\]
把\(ln\)拆开
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 付公主的背包的更多相关文章
- LuoguP4389 付公主的背包【生成函数+多项式exp】
题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...
- [题解] LuoguP4389 付公主的背包
这个题太神辣- 暴力背包就能获得\(30\)分的好成绩...... \(60\)分不知道咋搞..... 所以直接看\(100\)分吧\(QwQ\) 用一点生成函数的套路,对于一个体积为\(v\)的物品 ...
- luoguP4389 付公主的背包 多项式exp
%%%dkw 话说这是个论文题来着... 考虑生成函数\(OGF\) 对于价值为\(v\)的物品,由于有\(10^5\)的件数,可以看做无限个 那么,其生成函数为\(x^0 + x^{v} + x^{ ...
- 洛谷 P4389 付公主的背包 解题报告
P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...
- 洛谷P4389 付公主的背包--生成函数+多项式
题目链接戳这里 题目描述 有\(n\)件不同的商品,每件物品都有无限个,输出总体积为\([1,m]\)的方案数 思路 直接跑背包有\(30\) 考虑把每个物品的生成函数设出来,对于一件体积为\(v\) ...
- luogu P4389 付公主的背包
传送门 神仙题鸭!orz dkw 暴力就是完全背包 而完全背包可以和生成函数扯上关系,记第i种物品质量为\(a_i\),那么这种物品的生成函数\(G(i)=\sum_{j=0}^{\infty}x^{ ...
- luogu4389 付公主的背包
题目链接:洛谷 题目大意:现在有$n$个物品,每种物品体积为$v_i$,对任意$s\in [1,m]$,求背包恰好装$s$体积的方案数(完全背包问题). 数据范围:$n,m\leq 10^5$ 这道题 ...
- P3489 付公主的背包
题意:n<=1e5,m<=1e5,跑n个物品1到m容量的完全背包. 考虑暴力的做法就是把一些1/(1+x^a)的多项式乘起来即可. 考虑优化,取一下ln,转化为加法,然后exp回去就好了.
- 洛谷 P4389: 付公主的背包
题目传送门:洛谷 P4389. 题意简述: 有 \(n\) 个物品,每个物品都有无限多,第 \(i\) 个物品的体积为 \(v_i\)(\(v_i\le m\)). 问用这些物品恰好装满容量为 \(i ...
随机推荐
- C++中类型转换
static_cast 静态类型转换. 在编译的时候C++编译器会做类型检查,基本类型能转换,指针类型不进行转换. C语言中隐式类型转换的地方均可以使用static_cast. ...
- Android数据存储的五种方法汇总
本文介绍Android中的5种数据存储方式. 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPreferences存储数据 2 ...
- 【LeetCode】036. Valid Sudoku
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- C#中如何获取一个二维数组的两维长度,即行数和列数?以及多维数组各个维度的长度?
如何获取二维数组中的元素个数呢? int[,] array = new int[,] {{1,2,3},{4,5,6},{7,8,9}};//定义一个3行3列的二维数组int row = array. ...
- ECMAScript基本函数、概念区分总结
1.使用Number()和parseInt() parseFloat()转换区别. 详见<JavaScript高级程序设计>P30 Number()可以针对任何类型. parseInt() ...
- SpringMVC执行流程简介
1.用户向服务器发送请求,请求被SpringMVC的前端控制器DispatcherServlet截获. 2.DispatcherServlet对请求的URL(统一资源定位符)进行解析,得到URI(请求 ...
- VisualGDB系列3:安装VisualGDB
根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 1 系统需求 系统需求如下: Micro ...
- TP5隐藏url中的index.php
在public文件夹下,有个.htacess文件,没有则新建一个, 如果已有这个文件,原文件内容如下: <IfModule mod_rewrite.c> Options +FollowSy ...
- python 基础 操作文件和目录
获得当前目录路径 :os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 删除一个文件:os.remove(filename) 删除多个空目录 :os.removefir ...
- css之布局
布局一直是页面制作很重要的部分,有个良好的布局不仅在页面上呈现很好的效果,还对后续功能扩展有重要的作用.本文主要讨论一下几种布局: 水平居中布局 垂直居中布局 多列布局 自适应布局 stracky-f ...