好久没更博了

咕咕咕

现在多项式板子的常数巨大...周末好好卡波常吧....

LOJ #556


题意

给定$ m$种物品的出现次数$ B_i$以及大小$ A_i$

求装满大小为$[1..n]$的背包的方案数各是多少

数据范围全是$ 10^5$


$ Solution$

转化成生成函数求解

即是要求

$Ans=\prod\limits_{i=1}^m \sum\limits_{j=0}^{B_i} x^{A_i·j}$

等比数列收敛一下即是

$Ans= \prod\limits_{i=1}^m \frac{1-x^{(B_i+1)·A_i}}{1-x^{A_i}}$

直接乘复杂度巨大,考虑转求$ Ln(Ans)$

则有

$Ans=Exp(\sum\limits_{i=1}^m Ln(1-x^{(B_i+1)·A_i})-Ln(1-x^{A_i}))$

其中$ Ln(1-x)$的泰勒级数为$-\sum\limits_{i=1}^{\infty}\frac{x^i}{i}$

开个桶对所有指数记录一下,读入完成后调和级数累加即可

然后就是多项式$ Exp$的模版了

时间复杂度$ O(n \ log \ n)$


$ my \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define rt register int
#define ll long long
using namespace std;
namespace fast_IO{
const int IN_LEN=,OUT_LEN=;
char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-;
inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}
inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,,oh-obuf,stdout),oh=obuf;*oh++=x;}
inline void flush(){fwrite(obuf,,oh-obuf,stdout);}
}
using namespace fast_IO;
//#define getchar() getchar_()
//#define putchar(x) putchar_((x))
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans; namespace poly{
#define p 998244353
vector<int>R;
vector<int>get(int n){
vector<int>ret(n);
for(rt i=;i<n;i++)ret[i]=read();
return ret;
}
void print(const vector<int>A){for(auto i:A)write((i+p)%p),putchar(' ');}
int ksm(int x,int y=p-){
int ans=;
for(rt i=y;i;i>>=,x=1ll*x*x%p)if(i&)ans=1ll*ans*x%p;
return ans;
}
void NTT(int n,vector<int>&A,int fla){
A.resize(n);
for(rt i=;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
for(rt i=;i<n;i<<=){
int w=ksm(,(p-)//i);
for(rt j=;j<n;j+=i<<){
int K=;
for(rt k=;k<i;k++,K=1ll*K*w%p){
int x=A[j+k],y=1ll*K*A[i+j+k]%p;
A[j+k]=(x+y)%p,A[i+j+k]=(x-y)%p;
}
}
}
if(fla==-){
reverse(A.begin()+,A.end());
int invn=ksm(n);
for(rt i=;i<n;i++)A[i]=1ll*A[i]*invn%p;
}
}
vector<int>Resize(int n,vector<int>A){A.resize(n);return A;}
vector<int>Mul(vector<int>x,vector<int>y){
int lim=,sz=x.size()+y.size()-;
while(lim<=sz)lim<<=;R.resize(lim);
for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|(i&)*(lim>>);
NTT(lim,x,);NTT(lim,y,);
for(rt i=;i<lim;i++)x[i]=1ll*x[i]*y[i]%p;
NTT(lim,x,-);x.resize(sz);
return x;
}
vector<int>Inv(vector<int>A,int n=-){
if(n==-)n=A.size();
if(n==)return vector<int>(,ksm(A[]));
vector<int>b=Inv(A,(n+)/);
int lim=;while(lim<=n+n)lim<<=;R.resize(lim);
for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|(i&)*(lim>>);
A.resize(n);NTT(lim,A,);NTT(lim,b,);
for(rt i=;i<lim;i++)A[i]=1ll*b[i]*(2ll-1ll*A[i]*b[i]%p)%p;
NTT(lim,A,-);A.resize(n);
return A;
}
vector<int>Div(vector<int>A,vector<int>B){
int n=A.size(),m=B.size();
reverse(A.begin(),A.end());
reverse(B.begin(),B.end());
A.resize(n-m+),B.resize(n-m+);
int lim=;while(lim<=*(n-m+))lim<<=;R.resize(lim);
for(rt i=;i<lim;i++)R[i]=(R[i>>]>>)|(i&)*(lim>>);
vector<int>ans=Resize(n-m+,Mul(A,Inv(B)));
reverse(ans.begin(),ans.end());
return ans;
}
vector<int>Add(vector<int>A,vector<int>B){
int len=max(A.size(),B.size());A.resize(len);
for(rt i=;i<len;i++)(A[i]+=B[i])%=p;
return A;
}
vector<int>Sub(vector<int>A,vector<int>B){
int len=max(A.size(),B.size());A.resize(len);
for(rt i=;i<len;i++)(A[i]-=B[i])%=p;
return A;
}
vector<int>Mul(int x,vector<int>A){
for(rt i=;i<A.size();i++)A[i]=1ll*A[i]*x%p;
return A;
}
vector<int>deriv(vector<int>A){//求导
for(rt i=;i<A.size();i++)(A[i-]=1ll*A[i]*i%p);
A.pop_back();return A;
}
vector<int>integ(vector<int>A){//积分
A.push_back();
for(rt i=A.size()-;i>=;i--)A[i+]=1ll*A[i]*ksm(i+)%p;
A[]=;return A;
}
vector<int>Ln(const vector<int>A){return integ(Resize(A.size()-,Mul(deriv(A),Inv(A))));}
vector<int>Exp(vector<int>A,int n=-){
if(n==-)n=A.size();
if(n==)return vector<int>(,);
vector<int>A0=Resize(n,Exp(A,(n+)>>));
vector<int>now=Resize(n,Ln(A0));
for(rt i=;i<n;i++)now[i]=(A[i]-now[i])%p;now[]++;
return Resize(n,Mul(A0,now));
}
struct cp{
ll a,b,z;//a+bsqrt(z)
cp operator *(const cp s)const{
return {(1ll*a*s.a%p+1ll*b*s.b%p*z%p)%p,(1ll*a*s.b%p+1ll*b*s.a)%p,z};
}
};
cp ksm(cp x,int y){
cp ans={,,x.z};
for(rt i=y;i;i>>=,x=x*x)if(i&){
ans=x*ans;
}
return ans;
}
int Sqrt(int n){//求二次剩馀
if(ksm(n,(p-)/)!=)return -;
while(){
x=rand()%p;
if(ksm((1ll*x*x%p-n%p+p)%p,(p-)/)==)continue;
cp ret=ksm({x,,(1ll*x*x%p+p-n)%p},(p+)/);
return min(ret.a,p-ret.a);
}
}
vector<int>GetSqrt(vector<int>A,int n=-){
if(n==-)n=A.size();
if(n==)return vector<int>(,Sqrt(A[]));
vector<int>ans=Resize(n,GetSqrt(A,n+>>)),C(A.begin(),A.begin()+n);
return Resize(n,Mul(ksm(),Add(ans,Mul(Inv(ans),C))));
}
vector<int>Pow(vector<int>A,int k){
A[]=;
return Exp(Mul(k,Ln(A)));
}
//#undef p
};
using namespace poly;
int inv[],v[];
int main(){
n=read();m=read();
for(rt i=;i<=m;i++){
int a=read(),b=read();
if(1ll*a*(b+)<=n&&b)v[a*(b+)]--;
if(a<=n)v[a]++;
}
inv[]=inv[]=;
for(rt i=;i<=n;i++)inv[i]=1ll*inv[p%i]*(p-p/i)%p;
vector<int>ans(n+);
for(rt i=;i<=n;i++)if(v[i])
for(rt j=;i*j<=n;j++)(ans[i*j]+=1ll*v[i]*inv[j]%p)%=p;
ans=Exp(ans);
for(rt i=;i<=n;i++)writeln((ans[i]+p)%p);
return flush(),;
}

LOJ #556. 「Antileaf's Round」咱们去烧菜吧的更多相关文章

  1. 【刷题】LOJ 556 「Antileaf's Round」咱们去烧菜吧

    题目描述 你有 \(m\) 种物品,第 \(i\) 种物品的大小为 \(a_i\) ​,数量为 \(b_i\)​( \(b_i=0\) 表示有无限个). 你还有 \(n\) 个背包,体积分别为 \(1 ...

  2. 「LOJ 556 Antileaf's Round」咱们去烧菜吧

    「LOJ 556 Antileaf's Round」咱们去烧菜吧 最近在看 jcvb 的生成函数课件,顺便切一切上面讲到的内容的板子题,这个题和课件上举例的背包计数基本一样. 解题思路 首先列出答案的 ...

  3. LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)

    题面 传送门 题解 好吧我是不太会复杂度分析-- 我们对于每种颜色用一个数据结构维护(比方说线段树或者平衡树,代码里写的平衡树),那么区间询问很容易就可以解决了 所以现在的问题是区间修改,如果区间颜色 ...

  4. loj558 「Antileaf's Round」我们的CPU遭到攻击

    考完了可以发题解了. 做法是link-cut tree维护子树信息,并不需要维护黑树白树那些的. 下面是一条重链: 如果4是根的话,那么在splay上是这样的: 在splay中,子树的信息都已经计算完 ...

  5. Loj #2331. 「清华集训 2017」某位歌姬的故事

    Loj #2331. 「清华集训 2017」某位歌姬的故事 IA 是一名会唱歌的女孩子. IOI2018 就要来了,IA 决定给参赛选手们写一首歌,以表达美好的祝愿.这首歌一共有 \(n\) 个音符, ...

  6. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  7. Loj #2321. 「清华集训 2017」无限之环

    Loj #2321. 「清华集训 2017」无限之环 曾经有一款流行的游戏,叫做 *Infinity Loop***,先来简单的介绍一下这个游戏: 游戏在一个 \(n \times m\) 的网格状棋 ...

  8. Loj 2320.「清华集训 2017」生成树计数

    Loj 2320.「清华集训 2017」生成树计数 题目描述 在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\ ...

  9. 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题

    题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...

随机推荐

  1. c# 小数四舍五入,向上取整,向下取整,见角进元保留多个小数位数

    /// <summary> /// 实现数据的四舍五入法 /// </summary> /// <param name="v">要进行处理的数据 ...

  2. SP11470 TTM - To the moon

    嘟嘟嘟 主席树+区间修改. 以为是水题,写着写着发现区间修改标记下传会出问题,然后想了想发现以前做的只是单点修改. 那怎么办咧? 然后题解交了我标记永久化这个神奇的东西. 特别好理解,就是修改的时候直 ...

  3. SQL学习 DECODE

    from 百度百科: DECODE有什么用途呢? 先构造一个例子,假设我们想给这些职员加工资,其标准是:工资在8000元以下的加20%:工资在8000元或以上的加15%,通常的做法是,先选出记录中的工 ...

  4. php curl cookie 读写

    普通 curl post 请求 public static function curlPost($url, $post_fields = array(), $timeout = 5) { $timeo ...

  5. Docker镜像拉不下来?试试这些

    DaoCloud 加速器1.0(永久免费) DaoCloud是国内第一家Dock Hub加速器提供商 注意,加速器 2.0 需要使用 DaoCloud 自己的云服务器才可以使用.官方宣称会继续支持加速 ...

  6. 在SQL Server中如何进行UPDATE TOP .....ORDER BY?

    前言 今天在导入数据到系统后需要根据时间排序对刚导入的TOP N条进行数据更新,之前没遇到过UPDATE TOP...ORDER BY,以此作为备忘录. SQL SERVER之UPDATE TOP.. ...

  7. Linux(Ubuntu)使用日记(七)------终端控制器Terminator安装使用

    1.目的 实现分屏效果,如图: 如果使用系统自带的终端,可能会使这种效果: 综上所述,知道我们为什么要安装Terminator了吧. 2.安装过程 Terminator 的安装非常方便,在 Ubunt ...

  8. Shell命令-文件压缩解压缩之gzip、zip

    文件及内容处理 - gzip.zip 1.gzip:gzip压缩工具 gzip命令的功能说明 gzip 命令用于压缩文件.gzip 是个使用广泛的压缩程序,文件经它压缩过后,其名称后面会多出 .gz ...

  9. 使用Spring表达式语言进行装备--SpEL

    本文主要想记录最近的两个使用spring框架实现通过配置文件装备Bean,以及使用SpEL装备Bean. 1.使用配置文件装备Bean: 当我们写某些Bean的时候是希望这个Bean当中的属性是可以通 ...

  10. codeforces444A

    DZY Loves Physics CodeForces - 444A DZY loves Physics, and he enjoys calculating density. Almost eve ...