【刷题】LOJ 556 「Antileaf's Round」咱们去烧菜吧
题目描述

你有 \(m\) 种物品,第 \(i\) 种物品的大小为 \(a_i\) ,数量为 \(b_i\)( \(b_i=0\) 表示有无限个)。
你还有 \(n\) 个背包,体积分别为 \(1\) 到 \(n\) ,现在你很想知道用这些物品填满某个背包的方案数。
为了满足你的好奇心,你决定把填满每个背包的方案数都算一遍。
因为你其实只是闲得无聊,所以你只想知道方案数对 \(998244353\)( \(7\times 17\times 2^{23}+1\),一个质数)取模后的值。
输入格式
第一行两个非负整数,分别表示 \(n,m\)。
以下 \(m\) 行,每行两个非负整数,分别表示 \(a_i,b_i\) 。
输出格式
输出 \(n\) 个非负整数表示答案。
样例
样例输入
5 3
1 0
1 1
3 2
样例输出
2
2
3
4
4
样例解释
拼出 \(1\) ~ \(5\) 的方案分别如下:
\(\{1_1\},\{1_2\}\)
\(\{1_1,1_1\},\{1_1,1_2\}\)
\(\{1_1,1_1,1_1\},\{1_1,1_1,1_2\},\{3\}\)
\(\{1_1,1_1,1_1,1_1\},\{1_1,1_1,1_1,1_2\},\{1_1,3\},\{1_2,3\}\)
\(\{1_1,1_1,1_1,1_1,1_1\},\{1_1,1_1,1_1,1_1,1_2\},\{1_1,1_1,3\},\{1_1,1_2,3\}\)
数据范围与提示
\(0<n,m \leq 10^5,0 \leq a_i \leq 110000,0 \leq b_i \leq 10^6\)。
题解
数量无限的物品的生成函数为:\(\sum_{i=0}^{+\infty}x^{ia_i}=\frac{1}{1-x^{a_i}}\)
数量有限的物品的生成函数为:\(\sum_{i=0}^{b_i}x^{ia_i}=\frac{1-x^{(b_i+1)a_i}}{1-x^{a_i}}\)
将所有物品的生成函数乘起来就是答案的生成函数,即(假设全部都有限):
\(\begin{aligned}
ans
&= \prod_{i=1}^m\frac{1-x^{(b_i+1)a_i}}{1-x^{a_i}} \\
&= \exp{\sum_{i=1}^m (\ln (1-x^{(b_i+1)a_i})-\ln (1-x^{a_i}))}
\end{aligned}\)
然后我们知道:\(-\ln(1-x)=\sum_{i=1}^{+\infty}\frac{x^i}{i}\) ,所以
\(\ln (1-x^{(b_i+1)a_i})=\sum_{i=1}^{+\infty}-\frac{1}{i}x^{(b_i+1)a_i}\)
\(\ln (1-x^{a_i})=\sum_{i=1}^{+\infty}-\frac{1}{i}x^{a_i}\)
那么对于物品,可以 \(O(n \ln{n} )\) 地把它们的贡献加到OGF上,然后做多项式exp就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
#define ft first
#define sd second
#define pb(a) push_back(a)
#define PII std::pair<int,int>
#define PLL std::pair<ll,ll>
#define mp(a,b) std::make_pair(a,b)
#define ITR(a,b) for(auto a:b)
#define REP(a,b,c) for(register int a=(b),a##end=(c);a<=a##end;++a)
#define DEP(a,b,c) for(register int a=(b),a##end=(c);a>=a##end;--a)
const int MAXN=1<<21,Mod=998244353;
int M[MAXN];
ll OGF[MAXN],ans[MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline bool chkmin(T &x,T y){return y<x?(x=y,true):false;}
template<typename T> inline bool chkmax(T &x,T y){return y>x?(x=y,true):false;}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
namespace poly{
const int Mod=998244353;
int rev[MAXN];
ll b[MAXN],c[MAXN],tmp[MAXN],inv2,inv3,invm,pw[MAXN],ipw[MAXN],iv[MAXN];
inline ll qexp(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)res=res*a%Mod;
a=a*a%Mod;
b>>=1;
}
return res;
}
inline void init(int n)
{
inv2=qexp(2,Mod-2);inv3=qexp(3,Mod-2);
for(register int l=1;l<=(n<<2);l<<=1)
pw[l]=qexp(3,(Mod-1)/l),ipw[l]=qexp(inv3,(Mod-1)/l);
REP(i,1,n+n+1)iv[i]=qexp(i,Mod-2);
}
inline void NTT(ll *A,int n,int tp)
{
REP(i,0,n-1)if(i<rev[i])std::swap(A[i],A[rev[i]]);
for(register int l=2;l<=n;l<<=1)
{
ll wn=tp>0?pw[l]:ipw[l];
for(register int i=0;i<n;i+=l)
{
ll w=1;
for(register int j=0;j<(l>>1);++j)
{
ll A1=A[i+j],A2=1ll*A[i+j+(l>>1)]*w%Mod;
A[i+j]=(A1+A2)%Mod,A[i+j+(l>>1)]=(A1-A2+Mod)%Mod;
w=1ll*w*wn%Mod;
}
}
}
}
inline void Get_Mul(int n,ll *A,ll *B,ll *C)
{
int m,cnt;
for(m=1,cnt=0;m<n;m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
NTT(A,m,1);NTT(B,m,1);
REP(i,0,m-1)A[i]=1ll*A[i]*B[i]%Mod;
NTT(A,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,n-1)C[i]=1ll*A[i]*invm%Mod;
}
inline void Get_Inv(int len,ll *A,ll *B)
{
if(len==1)
{
B[0]=qexp(A[0],Mod-2);
return ;
}
Get_Inv((len+1)>>1,A,B);
int m,cnt;
for(m=1,cnt=0;m<(len<<1);m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
REP(i,0,len-1)tmp[i]=A[i];
REP(i,len,m-1)tmp[i]=0;
NTT(tmp,m,1);NTT(B,m,1);
REP(i,0,m-1)B[i]=(2ll*B[i]%Mod-1ll*B[i]*B[i]%Mod*tmp[i]%Mod+Mod)%Mod;
NTT(B,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,len-1)B[i]=1ll*B[i]*invm%Mod;
REP(i,len,m-1)B[i]=0;
}
inline void Get_Sqr(int len,ll *A,ll *B)
{
if(len==1)
{
B[0]=1;
return ;
}
Get_Sqr((len+1)>>1,A,B);
memset(b,0,sizeof(b));Get_Inv(len,B,b);
int m,cnt;
for(m=1,cnt=0;m<(len<<1);m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
REP(i,0,len-1)tmp[i]=A[i];
REP(i,len,m-1)tmp[i]=0;
NTT(B,m,1);NTT(tmp,m,1);NTT(b,m,1);
REP(i,0,m-1)B[i]=1ll*(tmp[i]+1ll*B[i]*B[i]%Mod)%Mod*b[i]%Mod*inv2%Mod;
NTT(B,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,len-1)B[i]=1ll*B[i]*invm%Mod;
REP(i,len,m-1)B[i]=0;
}
inline void Get_Div(int n1,ll *A,int n2,ll *B,ll *C,ll *D)
{
memset(c,0,sizeof(c));
REP(i,0,n2-1)c[i]=B[n2-1-i];
Get_Inv(n1-n2+1,c,b);
int m,cnt;
for(m=1,cnt=0;m<((n1-n2+1)<<1);m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
REP(i,0,n1-n2)tmp[i]=A[n1-1-i];
REP(i,n1-n2+1,m-1)tmp[i]=0;
NTT(tmp,m,1);NTT(b,m,1);
REP(i,0,m-1)tmp[i]=1ll*tmp[i]*b[i]%Mod;
NTT(tmp,m,-1);
invm=qexp(m,Mod-2);
memset(c,0,sizeof(c));
REP(i,0,n1-n2)C[n1-n2-i]=c[n1-n2-i]=1ll*tmp[i]*invm%Mod;
for(m=1,cnt=0;m<n1;m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
NTT(B,m,1);NTT(c,m,1);
REP(i,0,m-1)B[i]=1ll*B[i]*c[i]%Mod;
NTT(B,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,n2-2)D[i]=(A[i]-1ll*B[i]*invm%Mod+Mod)%Mod;
}
inline void Get_Der(int n,ll *A,ll *B)
{
REP(i,0,n-2)B[i]=1ll*A[i+1]*(i+1)%Mod;B[n-1]=0;
}
inline void Get_Int(int n,ll *A,ll *B)
{
REP(i,1,n-1)B[i]=1ll*A[i-1]*iv[i]%Mod;B[0]=0;
}
inline void Get_Ln(int n,ll *A,ll *B)
{
memset(b,0,sizeof(b));
Get_Inv(n,A,b);Get_Der(n,A,c);
int m,cnt;
for(m=1,cnt=0;m<(n<<1);m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
NTT(b,m,1);NTT(c,m,1);
REP(i,0,m-1)b[i]=1ll*b[i]*c[i]%Mod;
NTT(b,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,n-1)b[i]=1ll*b[i]*invm%Mod;
Get_Int(n,b,B);
}
inline void Get_Exp(int len,ll *A,ll *B)
{
if(len==1)
{
B[0]=1;
return ;
}
Get_Exp((len+1)>>1,A,B);Get_Ln(len,B,c);
int m,cnt;
for(m=1,cnt=0;m<(len<<1);m<<=1,++cnt);
REP(i,0,m-1)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
REP(i,0,len-1)tmp[i]=(A[i]-c[i]+(i==0)+Mod)%Mod;
REP(i,len,m-1)tmp[i]=0;
NTT(tmp,m,1);NTT(B,m,1);
REP(i,0,m-1)B[i]=1ll*tmp[i]*B[i]%Mod;
NTT(B,m,-1);
invm=qexp(m,Mod-2);
REP(i,0,len-1)B[i]=1ll*B[i]*invm%Mod;
REP(i,len,m-1)B[i]=0;
}
}
int main()
{
int n,m;read(n);read(m);poly::init(n+1);
REP(i,1,m)
{
int a,b;read(a);read(b);
if(a<=n)M[a]++;
if(1ll*(b+1)*a<=n&&b)M[(b+1)*a]--;
}
REP(i,1,n)if(M[i])REP(j,1,n/i)OGF[i*j]=((OGF[i*j]+1ll*M[i]*poly::iv[j]%Mod)%Mod+Mod)%Mod;
poly::Get_Exp(n+1,OGF,ans);
REP(i,1,n)write(ans[i],'\n');
return 0;
}
【刷题】LOJ 556 「Antileaf's Round」咱们去烧菜吧的更多相关文章
- LOJ #556. 「Antileaf's Round」咱们去烧菜吧
好久没更博了 咕咕咕 现在多项式板子的常数巨大...周末好好卡波常吧.... LOJ #556 题意 给定$ m$种物品的出现次数$ B_i$以及大小$ A_i$ 求装满大小为$[1..n]$的背包的 ...
- 「LOJ 556 Antileaf's Round」咱们去烧菜吧
「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...
- LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)
题面 传送门 题解 好吧我是不太会复杂度分析-- 我们对于每种颜色用一个数据结构维护(比方说线段树或者平衡树,代码里写的平衡树),那么区间询问很容易就可以解决了 所以现在的问题是区间修改,如果区间颜色 ...
- loj558 「Antileaf's Round」我们的CPU遭到攻击
考完了可以发题解了. 做法是link-cut tree维护子树信息,并不需要维护黑树白树那些的. 下面是一条重链: 如果4是根的话,那么在splay上是这样的: 在splay中,子树的信息都已经计算完 ...
- Loj 2320.「清华集训 2017」生成树计数
Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...
- [LOJ#2329]「清华集训 2017」我的生命已如风中残烛
[LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...
- [LOJ#2328]「清华集训 2017」避难所
[LOJ#2328]「清华集训 2017」避难所 试题描述 "B君啊,你当年的伙伴都不在北京了,为什么你还在北京呢?" "大概是因为出了一些事故吧,否则这道题就不叫避难所 ...
- [LOJ#2327]「清华集训 2017」福若格斯
[LOJ#2327]「清华集训 2017」福若格斯 试题描述 小d是4xx9小游戏高手. 有一天,小d发现了一个很经典的小游戏:跳青蛙. 游戏在一个 \(5\) 个格子的棋盘上进行.在游戏的一开始,最 ...
- [LOJ#2326]「清华集训 2017」简单数据结构
[LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...
随机推荐
- SDK安装详解以及adb的来源
首先,下载Android SDK Tools,翻过墙的朋友可以去Google Android的官网上下载(http://developer.android.com/sdk/index.html) 选择 ...
- ORACLE 当字段中有数据如何修改字段类型
创建视图的时候,因为表太多,里面一些字段类型不一样,PL/SQL报错,为‘表达式必须具有对应表达式相同的数据类型’,发现后,一个字段的类型为CLOB和VARCHAR2(4000)两种,将CLOB进行修 ...
- day 7-21 pymysql模块
一.安装的两种方法 第一种: #安装 pip3 install pymysql 第二种: 二.链接,执行sql,关闭(游标) import pymysql user = input("use ...
- day 7-20 视图,触发器,事务
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- linux audit审计(7)--读懂audit日志
让我们先来构造一条audit日志.在home目录下新建一个目录,然后配置一条audit规则,对这个目录的wrax,都记录审计日志: auditctl -w /home/audit_test -p wr ...
- 对于tomcat通过catalina.sh停止服务后,tomcat进程没有退出问题解决办法
例:tomcat路径及名称为/data/apache-tomcat-7.0.67/ vim /data/apache-tomcat-7.0.67/bin/catalina.sh 找到org.apach ...
- mvn clean deploy
如果是 mthrift的话,需要部署,就用 mvn clean deploy; 先进入 cd qcs.appeal.client ,然后执行:mvn clean deploy;
- has invalid type <class 'numpy.ndarray'>, must be a string or Tensor
转自: https://blog.csdn.net/jacke121/article/details/78833922 has invalid type <class 'numpy.ndarra ...
- 去掉AMD锐龙和Intel Kaby Lake的不支持的硬件的提示
Windows 7和Windows 8.1都不支持AMD Ryzen 锐龙系列和Intel最新的Kaby Lake系列,Windows Update 更新之后总是会提示“不支持的硬件(Unsuppor ...
- git指令详解总结
Git是目前最流行的版本管理系统,学会Git几乎成了开发者的必备技能. Git有很多优势,其中之一就是远程操作非常简便.本文详细介绍5个Git命令,它们的概念和用法,理解了这些内容,你就会完全掌握Gi ...