完全背包方案计数问题的FFT优化。
首先写成生成函数的形式:对重量为V的背包,它的生成函数为$\sum\limits_{i=0}^{+\infty}\frac{x^{Vi}}{i}=\frac{1}{1-x^{V}}$
于是答案就是$\prod \frac{1}{1-x^{V_k}}$。
直接做显然会超时,考虑使用ln将乘法变为加法。
https://www.cnblogs.com/cjyyb/p/10132855.html

 #include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define mem(a) memset(a,0,sizeof(a))
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=,mod=,inv2=(mod+)/;
int n,m,v,cnt[N],rev[N],inv[N],X[N],Y[N],A[N],D[N],E[N],F[N]; void Print(int a[],int n=::n){ for (int i=; i<n; i++) printf("%d ",a[i]); puts(""); } int ksm(int a,int b){
int res=;
for (; b; a=1ll*a*a%mod,b>>=)
if (b & ) res=1ll*res*a%mod;
return res;
} void NTT(int a[],int n,bool f){
for (int i=; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=; i<n; i<<=){
int wn=ksm(,f ? (mod-)/(i<<) : (mod-)-(mod-)/(i<<));
for (int p=i<<,j=; j<n; j+=p){
int w=;
for (int k=; k<i; k++,w=1ll*w*wn%mod){
int x=a[j+k],y=1ll*w*a[i+j+k]%mod;
a[j+k]=(x+y)%mod; a[i+j+k]=(x-y+mod)%mod;
}
}
}
if (f) return;
int inv=ksm(n,mod-);
for (int i=; i<n; i++) a[i]=1ll*a[i]*inv%mod;
} void mul(int a[],int b[],int l){
int n=,L=;
for (; n<(l<<); n<<=) L++;
for (int i=; i<n; i++) rev[i]=(rev[i>>]>>)|((i&)<<(L-));
NTT(a,n,); NTT(b,n,);
for (int i=; i<n; i++) a[i]=1ll*a[i]*b[i]%mod;
NTT(a,n,); NTT(b,n,);
} void Inv(int a[],int b[],int l){
if (l==){ b[]=ksm(a[],mod-); return; }
Inv(a,b,l>>); int n=,L=;
for (; n<(l<<); n<<=) L++;
for (int i=; i<n; i++) rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for (int i=; i<l; i++) A[i]=a[i];
NTT(A,n,); NTT(b,n,);
for (int i=; i<n; i++) b[i]=1ll*b[i]*(-1ll*A[i]*b[i]%mod+mod)%mod;
NTT(b,n,);
for (int i=l; i<n; i++) b[i]=;
for (int i=; i<n; i++) A[i]=;
} void Deri(int a[],int b[],int l){
for (int i=; i<l; i++) b[i-]=1ll*i*a[i]%mod;
} void Inte(int a[],int b[],int l){
for (int i=; i<l; i++) b[i]=1ll*a[i-]*inv[i]%mod; b[]=;
} void Ln(int a[],int b[],int l){
Deri(a,D,l); Inv(a,E,l); mul(D,E,l); Inte(D,b,l);
for (int i=; i<(l<<); i++) D[i]=E[i]=;
} void Exp(int a[],int b[],int l){
if (l==){ b[]=; return; }
Exp(a,b,l>>); Ln(b,F,l); int n=,L=;
for (; n<(l<<); n<<=) L++;
for (int i=; i<n; i++) rev[i]=(rev[i>>]>>)|((i&)<<(L-));
for (int i=; i<l; i++) F[i]=(-F[i]+a[i]+mod)%mod; F[]=(F[]+)%mod;
NTT(F,n,); NTT(b,n,);
for (int i=; i<n; i++) b[i]=1ll*b[i]*F[i]%mod;
NTT(b,n,);
for (int i=l; i<n; i++) b[i]=;
for (int i=; i<n; i++) F[i]=;
} int main(){
freopen("4389.in","r",stdin);
freopen("4389.out","w",stdout);
scanf("%d%d",&n,&m);
int l=; for (; l<=m; l<<=); inv[]=inv[]=;
rep(i,,l) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
rep(i,,n) scanf("%d",&v),cnt[v]++;
rep(i,,m) if (cnt[i]) for (int j=; j*i<=m; j++) X[j*i]=(X[j*i]+1ll*cnt[i]*inv[j])%mod;
Exp(X,Y,l);
rep(i,,m) printf("%d\n",Y[i]);
return ;
}

[luogu4389]付公主的背包(多项式exp)的更多相关文章

  1. luoguP4389 付公主的背包 多项式exp

    %%%dkw 话说这是个论文题来着... 考虑生成函数\(OGF\) 对于价值为\(v\)的物品,由于有\(10^5\)的件数,可以看做无限个 那么,其生成函数为\(x^0 + x^{v} + x^{ ...

  2. Luogu4389 付公主的背包(生成函数+多项式exp)

    显然构造出生成函数,对体积v的物品,生成函数为1+xv+x2v+……=1/(1-xv).将所有生成函数乘起来得到的多项式即为答案,设为F(x),即F(x)=1/∏(1-xvi).但这个多项式的项数是Σ ...

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

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

  4. luogu4389 付公主的背包

    题目链接:洛谷 题目大意:现在有$n$个物品,每种物品体积为$v_i$,对任意$s\in [1,m]$,求背包恰好装$s$体积的方案数(完全背包问题). 数据范围:$n,m\leq 10^5$ 这道题 ...

  5. 洛谷 P4389 付公主的背包 解题报告

    P4389 付公主的背包 题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装\(10^5\)大小的东西 付公主有\(n\)种商品,她要准备出摊了 每种商品体积为\(V_i\),都有\ ...

  6. LuoguP4389 付公主的背包【生成函数+多项式exp】

    题目背景 付公主有一个可爱的背包qwq 题目描述 这个背包最多可以装10^5105大小的东西 付公主有n种商品,她要准备出摊了 每种商品体积为Vi,都有10^5105件 给定m,对于s\in [1,m ...

  7. 【Luogu4389】付公主的背包

    题目 传送门 解法 答案显然是\(n\)个形如\(\sum_{i \geq 1} x^{vi}\)的多项式的卷积 然而直接NTT的时间复杂度是\(O(nm\log n)\) 我们可以把每个多项式求\( ...

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

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

  9. luogu P4389 付公主的背包

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

随机推荐

  1. [转]坐在马桶上看算法:只有五行的Floyd最短路算法

    此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在“Communications of the ACM”上.同年Stephen Warshall(史蒂芬·沃舍尔)也独立发表了 ...

  2. ispoweroftwo 判断2的次幂

    首先结果是: public bool IsPowerOfTwo(int n) { if(n<1) return false;//2的次幂一定大于0 return ((n & (n -1) ...

  3. java 多线程 Future callable

    面向对象5大设计原则 1.单一职责原则  一个类只包含它相关的方法,增删改查.一个方法只包含单一的功能,增加.一个类最多包含10个方法,一个方法最多50行,一个类最多500行.重复的代码进行封装,Do ...

  4. OpenStack Benchmark - Rally

    作为以基于OpenStack的云平台的基准测试工具 -- Rally, 其功能不仅是测试云的性能&&稳定性, 还可以安装OpenStack,以及以良好的表现形式(web 页面)展现测试 ...

  5. Java集合之Collection与之子类回顾

    Java学习这么久,打算这几天回顾下java的基本知识点,首先是集合. 一.常用集合类关系图 Collection |___List 有序,可重复 |___ArrayList  底层数据结构是数组,增 ...

  6. MongoDB安全:所有操作(Privilege Actions)

    本文展示了两张思维导图,分别是MongoDB 3.6.4.0的所有权限操作,未做深入研究,仅仅是列出来. 3.6总共9类105个操作,4.0版本比3.6多了两类操作,同时增加了3个操作,共11类108 ...

  7. netstat-ll-grep-nohup-df-supervisord

    ============http://man.linuxde.net/=========== 0 vi / n是查找下一个,alt+n是上一个  u撤销上一步,回到上一步 1. 根据进程号(4974) ...

  8. python网络编程--线程join和Daemon(守护进程)

    一:什么情况下使用join join([timeout])调用join函数会使得主调线程阻塞,直到被调用线程运行结束或超时. 参数timeout是一个数值类型,用来表示超时时间,如果未提供该参数,那么 ...

  9. MyBatis3-实现MyBatis分页

    此文章中的例子是沿用上一篇文章http://www.cnblogs.com/EasonJim/p/7055499.html的Spring MVC集成的例子改装的. MyBatis分页有以下方式实现: ...

  10. group by 和 distinct 去重比较

    distinct方式就是两两对比,需要遍历整个表.group by分组类似先建立索引再查索引,所以两者对比,小表destinct快,不用建索引.大表group by快.一般来说小表就算建索引,也不会慢 ...