#4155. 咱们去烧菜吧

题意
内存限制:512 MiB
时间限制:1000 ms

你有 $m$ 种物品,第 $i$ 种物品的大小为 $a_i$,数量为 $b_i$($b_i=0$ 表示有无限个)。

你还有 $n$ 个背包,体积分别为 $1$ 到 $n$,现在你很想知道用这些物品填满某个背包的方案数。

为了满足你的好奇心,你决定把填满每个背包的方案数都算一遍。

因为你其实只是闲得无聊,所以你只想知道方案数对 $998244353$($7\times 17\times 2^{23}+1$,一个质数)取模后的值。

$0< n,m\le 10^5, 0\le a_i\le 110000,0\le b_i\le 10^6$。

题解

把第 $i$ 个物品的生成函数写出,设 $b_i>0$,即 $F_i(x)=\sum_{j=0}^{b_i} x^{a_i \times j}=\frac{1-x^{a_i \times (b_i+1)}}{1-x^{a_i}}$

那么当 $b_i=0$ 时, $F_i(x)=\sum_{j=0}^{\infty} x^{a_i \times j}=\frac{1}{1-x^{a_i}}$

则最后的答案的生成函数 $G(x)=\prod_{i=1}^nF_i(x)$

两边取对数,即 $\ln G(x)=\ln (\prod_{i=1}^nF_i(x))=\sum_{i=1}^n \ln F_i(x)=\sum_{i=1}^n(\ln (1-x^{a_i \times (b_i+1)})-\ln(1-x^{a_i}))$

又知道 $\ln(1-x^k)=\sum_{i=1}^{\infty} \frac{x^{i \times k}}{i}$

所以对于每个 $k$ ,都会对 $x^{i \times k}$ 的系数造成影响,所以这一部分可以 $O(n\ln n)$ 预处理

所以最后做个多项式 $exp$ 即可

代码

#include <bits/stdc++.h>
#define I inline
using namespace std;
const int P=998244353,N=5e5+5;
int n,m,a[N],b[N],r[N],t,p,G[2]={3,332748118};
int A[N],B[N],C[N],D[N],E[N],F[N],jc[N],ny[N];
I int X(int x){if (x>=P) x-=P;return x;}
I int inv(int x){return 1ll*jc[x-1]*ny[x]%P;}
I int K(int x,int y){
    int A=1;
    for (;y;y>>=1,x=1ll*x*x%P)
        if (y&1) A=1ll*A*x%P;
    return A;
}
I void Ntt(int *g,bool o){
    for (int i=0;i<t;i++)
        if (i<r[i]) swap(g[i],g[r[i]]);
    for (int wn,i=1;i<t;i<<=1){
        wn=K(G[o],(P-1)/(i<<1));
        for (int x,y,j=0;j<t;j+=(i<<1))
            for (int w=1,k=0;k<i;k++,w=1ll*w*wn%P)
                x=g[j+k],y=1ll*w*g[i+j+k]%P,
                g[j+k]=X(x+y),g[i+j+k]=X(x-y+P);
    }
    if (o)
        for (int i=0,v=K(t,P-2);i<t;i++)
            g[i]=1ll*v*g[i]%P;
}
I void dao(int *a,int *b,int l){
    for (int i=1;i<l;i++)
        b[i-1]=1ll*i*a[i]%P;
    b[l]=b[l-1]=0;
}
I void jifen(int *a,int *b,int l){
    for (int i=1;i<l;i++)
        b[i]=1ll*a[i-1]*inv(i)%P;
    b[0]=0;
}
I void pre(int l){
    for (t=1,p=0;t<l+l;t<<=1,p++);
    for (int i=0;i<t;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));
}
I void getinv(int *a,int *b,int l){
    if (l==1){
        b[0]=K(a[0],P-2);return;
    }
    getinv(a,b,(l+1)>>1);
    for (int i=0;i<l;i++)
        A[i]=a[i],B[i]=b[i];
    pre(l);Ntt(A,0);Ntt(B,0);
    for (int i=0;i<t;i++)
        A[i]=1ll*A[i]*B[i]%P*B[i]%P;
    Ntt(A,1);for (int i=0;i<l;i++)
        b[i]=X(X(b[i]+b[i])-A[i]+P);
    for (int i=0;i<t;i++) A[i]=B[i]=0;
}
I void getln(int *a,int *b,int l){
    dao(a,C,l);getinv(a,D,l);
    pre(l);Ntt(C,0);Ntt(D,0);
    for (int i=0;i<t;i++)
        C[i]=1ll*C[i]*D[i]%P;
    Ntt(C,1);jifen(C,b,l);
    for (int i=0;i<t;i++) C[i]=D[i]=0;
}
I void getexp(int *a,int *b,int l){
    if (l==1){b[0]=1;return;}
    getexp(a,b,(l+1)>>1);
    for (int i=0;i<l;i++) E[i]=b[i];
    getln(b,F,l);
    for (int i=0;i<l;i++)
        F[i]=X(a[i]-F[i]+P);
    F[0]=X(F[0]+1);pre(l);
    Ntt(F,0);Ntt(E,0);
    for (int i=0;i<t;i++)
        E[i]=1ll*E[i]*F[i]%P;
    Ntt(E,1);
    for (int i=0;i<l;i++) b[i]=E[i];
    for (int i=0;i<t;i++) E[i]=F[i]=0;
}
int main(){
    scanf("%d%d",&n,&m);
    for (int x,y,i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        if (x<=n) a[x]++;
        if (y && 1ll*x*(y+1)<=1ll*n)
            a[x*(y+1)]--;
    }
    jc[0]=1;
    for (int i=1;i<=n;i++)
        jc[i]=1ll*i*jc[i-1]%P;
    ny[n]=K(jc[n],P-2);
    for (int i=n;i;i--)
        ny[i-1]=1ll*i*ny[i]%P;
    for (int i=1;i<=n;i++){
        if (!a[i]) continue;
        if (a[i]<0) a[i]+=P;
        for (int j=1;j*i<=n;j++)
            b[i*j]=X(b[i*j]+1ll*a[i]*inv(j)%P);
        a[i]=0;
    }
    getexp(b,a,n+1);
    for (int i=1;i<=n;i++)
        printf("%d\n",a[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/xjqxjq/p/10679284.html

时间: 2024-11-02 14:57:29

#4155. 咱们去烧菜吧的相关文章

烧菜列举

1:满天星:青椒+鸡蛋+火腿. 2:味虾米:虾仁+胡萝卜+黄瓜.(虾仁用淀粉+蛋清研制20分钟) 3:秘制鲜肉汤:瘦肉研制 4:西红柿炒鸡蛋:西红柿(用热水烫4秒钟)+鸡蛋 5:可乐鸡翅:鸡翅(淀粉研制20分钟,刀割) 6:酸辣土豆丝:(土豆丝切好后洗清) 7:红烧鱼(鱼研制1个小时) 8:小炒肉:肉用淀粉腌制

富二代用微信卖菜,结果悲剧

在黄凯偌大的办公桌上,一只干巴巴的苹果甚是惹眼:拳头大小,表皮发黄,一道道皱褶就像岁月的沟壑,透出点沧桑的味道. "这是我过年时放在这里的,虽然脱水严重,但一点没有腐烂.明显用过防腐剂,还打过蜡."面对记者,1989年出生的黄凯侃侃而谈,"我每天对着这个苹果,就是希望用它来提醒自己,要做安全放心的产品." 10天前,微信卖菜平台正式上线.作为投资者,黄凯打算用四五年时间,改变和他同样年轻的一批金华人的生活习惯:微信点点,健康的蔬菜水果和厨房佐料,就会自动送上门来.

简单的菜,不简单的爱

今日无事,小王看了很多烧菜的视频,手痒痒的,决定亲自下厨,一则锤炼自己的厨艺,二则要弘扬中华的美食文化,但是具体做什么菜,小王有点犯难了,毕竟自己没有下厨过.这菜不能太简单,否则失去了亲自的意义,也不能太复杂,否则没有下厨的必要,最后钦定了:青椒炒肉丝.于是小王看了相关视频,发现了每个视频的做法都不一样,有些做咸,有些烧甜,有些先炒青椒,有些先炸肉丝,小王越看越糊涂,反而感觉他们的图片是美颜过的,他们的视频是剪辑过的,不大真实.小王跟着视频做了几次,色相难看,味道不对.忽然间,小王想起了一个人:

卖菜也能有新招

实习时间:2016/02/05 ——2016/02/24 实习地点:广西省桂林市平乐县菜市 实习报告: 早早学校就放假了,当时也没有找到好的实习工作,所以就先回了家.回家回的早也有早的烦恼,当时朋友同学都还在上学没回家,爸妈就叫我去卖菜了.世界上没有任何事情是可以很轻松做完的,卖菜也一样.卖菜最烦的就是等待,最困的就是早起晚归. 头天下午就去菜地里面把要的菜和菜农们说好,等第二天一大早菜农们就会把菜送到我们卖菜的档口去. 这就是其中一天去地上看的菜. 第二天一大早就去搬菜.摆菜了. 枯燥而无谓的

生鲜电商三大难题未解 任性烧钱也白搭

生鲜电商为何是"死海":①标准化问题:②损耗和成本:③凌驾于标准化与冷链之上的"最后一公里",如何以"保鲜"模式送到消费者手中.三大难题解决不了,生鲜电商这档子事,其实就是烧钱也烧不出个所以然来. 文/张书乐 刊载于<销售与市场>管理版2015年06期 3月8日,苏宁超市公司正式宣布进军生鲜电商市场,开售自营生鲜产品,并命名为"苏鲜生".之前一天,步步高董事长王填宣布,4月底步步高云猴网生鲜正式上线.而在年前,并购

如何利用JLINK烧写U-boot到NAND Flash中

原文:http://blog.csdn.net/yanghao23/article/details/7689534  很多同学使用笔记本作为自己的ARM开发和学习的平台,绝大多数笔记本都没有并口,也就是无法使用JTag调试和烧写程序到Nand Flash中,幸好我们还有JLINK,用JLINK烧写U-boot到Nor Flash中很简单,大部分NOR Flash都已经被JLink的软件SEGGER所支持,而新手在学习的时候经常会实验各种各样的命令,最悲剧的莫过于将NAND Flash中原有的bo

《大道至简》第六章读后感

语言只是工具,就像在第一章中提到的那句话“成天讨论这门语言好,或者那门语言坏的人,甚至是可悲的.”语言是用来实现我们想法的工具,仅此而已. 就像自然界中永恒的定律:弱肉强食.这句话从自然界起源到现在都无可置疑,而“程序=算法+结构”这个等式在开发的世界里也有着相同的地位. 经过无数次实践的积累,方法也就呼之欲出.随着一遍遍的回顾.理解和分析,经验也在不断地增加.这不是你不断写代码就能实现的,不断地写只会让你的错误越来越多,你甚至会在同一个地方跌倒无数次,你以为你得到的是经验,实际上,你只是在浪费

[转]hadoop,spark,storm,pig,hive,mahout等到底有什么区别和联系?

摘自知乎大神的论述 作者:Xiaoyu Ma链接:https://www.zhihu.com/question/27974418/answer/38965760来源:知乎著作权归作者所有,转载请联系作者获得授权. 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它比作一个厨房所以需要的各种工具.锅碗瓢盆,各有各的用处,互相之间又有重合.你可以用汤锅直接当碗吃饭喝汤,你可以用小刀或者刨子去皮.但是每个工具有自己的特性,虽然奇怪

编程同写作,写代码只是在码字

编程同写作,写代码只是在码字 作者: Phodal Huang  发布时间: 2016-06-30 21:51  阅读: 12842 次  推荐: 43   原文链接   [收藏] 看到一篇文章<We Are Typists First, Programmers Second>,日期是2008年,好早的一篇文章.当现在打算以一个新人的身份重新进入编程领域,或许是受<重来>的影响,或者只是在重新思考——我们究竟应该如何去编程. 写代码只相当于写字 编程这件事情实际上一点儿也不难,当我