完全背包方案计数问题的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. host映射方法

    host映射: host是根据TCP/IP for Windows 的标准来工作的,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Host name(主机名)的规 ...

  2. Python——脚本(calculator)

    <Python基础教程>(第二版) P123 书中原代码如下: class Calculator: def calculator(self,expression): self.value ...

  3. 关于new Handler()与new Handler(Looper.getMainLooper())区别

    如果你不带参数的实例化:Handler handler=new Handler();那么这个会默认用当前线程的Looper对象. 一般而言,如果你的Handler是要用来刷新UI的,那么就需要在主线程 ...

  4. C#基础学习之FileStream

    FileStream和File的区别  后者比前者给内存带来压力大. FileStream可以操作字节也就是可以保存任何类型的文件. 1.FileStream读文件操作 //OpenOrCreate: ...

  5. RobotFramework基本用法(二)

    双击打开C:\Python27\Scripts目录下的 ride.py 一,定义变量,打印 1,右键File-->New Poreject,在项目下右键New suite,在套件下右键 New ...

  6. mac 下安装pip

    pip是常用的Python包管理工具,类似于Java的maven.用python的同学,都离不开pip. 在新mac中想用home-brew安装pip时,遇到了一些小问题: bogon:~ wangl ...

  7. java基础21 System类和Runtime类

    一.System系统类 1.1.System系统类 主要用于获取系统信息 1.2.System类的常用方法 arraycopy(Object src, int srcPos, Object dest, ...

  8. 程序设计分层思想和DAO设计模式的开发

    无论是一个应用程序项目还是一个Web项目,我们都可以按照分层思想进行程序设计.对于分层,当下最流行划分方式是:表现层+控制层+业务层+数据层.其中,业务层和数据层被统称为后台业务层,而表现层和控制层属 ...

  9. Unix IPC之基于共享内存的计数器

    目的 本文主要实现一个基于共享内存的计数器,通过父子进程对其访问. 本文程序需基于<<Unix网络编程-卷2>>的环境才能运行.程序中大写开头的函数为其小写同名函数的包裹函数, ...

  10. Ubuntu 搭建etcd

    一.简介 etcd是一个高可用的分布式键值(key-value)数据库.etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现. 提供配置共享和服务发现的系统比较多,其中最为大家熟知的是 ...