好久没更博了

咕咕咕

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

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. springboot+mybatis+pagehelper

    springboot+mybatis+pagehelper整合 springboot   版本2.1.2.RELEASE mybatis  版本3.5 pagehelper 版本5.18 支持在map ...

  2. 001_python多进程实例

    一.工作中需要执行zk数据对比,需要按照机器进行并发,举例以下的例子 # coding:utf8 # !/usr/bin/python import time from multiprocessing ...

  3. 为奋战在HIS创新路上的医院信息科赋能

    为奋战在HIS创新路上的医院信息科赋能 南京都昌信息科技有限公司 袁永福 2017-7 ◆◆前言 近日,上海瑞金医院向我司表示:“我院从2000年开始自主开发医院信息系统,走出了一条可持续的信息化发展 ...

  4. python多线程和多进程

    1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发 ...

  5. CentOS 7 rpm -i 时 警告warning: /var/tmp/rpm-tmp.z7O820: Header V4 RSA/SHA512 Signature, key ID a14fe591: NOKEY 解决方法

    这是由于yum安装了旧版本的GPG keys造成的,解决办法就是 运行下面命令即可 # rpm --import /etc/pki/rpm-gpg/RPM* 查询已安装的rpm源 # rpm -qa ...

  6. mysql-笔记--增删改查

    查看数据库:可以使用 show databases; 命令查看已经创建了哪些数据库 指定数据库:在登录后使用 use 语句指定, 命令: use 数据库名;要对一个数据库进行操作, 必须先选择该数据库 ...

  7. 如何批量修改网页 更新网站 一键保存 windows查看和排序

    批量打开需要修改的网页,一键保存:一个网站会由很多网页组成,当需要大量更新的时候,如果一个个进行打开修改,效率会很低,内容修改不多,且容易修改的时候,可以用editplus这种小编辑软件批量打开,批量 ...

  8. 常用的flex布局

    演示地址:https://xibushijie.github.io/static/flex.html

  9. Flask 模板系统

    模板 基本数据类型 可以执行python语法,如:dict.get(), list['xx'] 比django 更加亲近于 python 传入函数 - django,自动执行 - flask,不自动执 ...

  10. 在Ubuntu上使用离线方式快速安装K8S v1.11.1

    在Ubuntu上使用离线方式快速安装K8S v1.11.1 0.安装包文件下载 https://pan.baidu.com/s/1nmC94Uh-lIl0slLFeA1-qw v1.11.1 文件大小 ...