多项式全家桶学习笔记(应用)
一.斯特林数
1.1 第一类斯特林数·行
注意到
所以问题转化为怎么求 \(x^\overline n\)。
考虑分治。
所以问题就转化成了给定 \(f(x)\),怎么快速计算出 \(f(x+c)\)。
设
所以
是典型的减法卷积。
注意当计算 \(x^\overline {2n+1}\) 的时候还应再乘上 \((x+2n)\),直接 \(O(n)\) 乘即可。
设复杂度为 \(T(x)\),则 \(T(x)=T(\frac{x}{2})+n\log n\),由主定理可得 \(T(n)=n\log n\)。
Code
vec move(vec f,int c){
int n=f.size();
vec A(n),B(n);
for(int i=0,t=1;i<n;i++,t=1LL*t*c%P)A[i]=1LL*fac[i]*f[i]%P,B[n-i-1]=1LL*invfac[i]*t%P;
vec ret=mul(A,B,n<<1);
for(int i=0;i<n;i++)ret[i]=1LL*ret[i+n-1]*invfac[i]%P;
ret.resize(n);
return ret;
}
vec solve(int n){
if(n==1){
vec ans;
ans.push_back(0);
ans.push_back(1);
return ans;
}
vec f=solve(n>>1);
vec g=move(f,n>>1);
vec ans=mul(f,g,n+1);
if(n&1)for(int i=n;i;i--)ans[i]=(ans[i-1]+1LL*ans[i]*(n-1)%P)%P;
ans.resize(n+1);
return ans;
}
1.2 第一类斯特林数·列
考虑式子
一方面
另一方面
所以
考虑 \(\ln(x+1)\) 的泰勒展开
以及 \(\ln(\frac{1}{1-x})\) 的泰勒展开
所以
多项式快速幂即可。
注意由于 \([x^0]\ln(\frac{1}{1-x})=0\),所以应先把它平移一位后再进行计算。
复杂度 \(O(n\log n)\)。
Code
int main(){
IO>>n>>k;
prep(n<<1);
vec f(n);
for(int i=0;i<n;i++)f[i]=inv[i+1];
vec g=getpow(f,n,k);
vec ans(n+1);
for(int i=k;i<=n;i++)ans[i]=1LL*g[i-k]*invfac[k]%P*fac[i]%P;
for(int i=0;i<=n;i++)IO<<ans[i]<<' ';
return 0;
}
1.3 第二类斯特林数·行
这是最简单的一个。
注意到通项公式
是卷积的形式,所以直接卷积即可。
\(O(n\log n)\)。
Code
int main(){
IO>>n;
prep(n<<1);
for(ll i=0;i<=n;i++){
f[i]=qpow(i,n)*invfac[i]%P;
g[i]=invfac[i];
if(i&1)g[i]=P-g[i];
}
mul(f,g,(n<<1));
for(ll i=0;i<=n;i++)IO<<f[i]<<' ';
return 0;
}
1.4 第二类斯特林数·列
这题有两种做法,复杂度也不同。
由于
所以设
那么
所以
用分治 NTT 算分母,然后求逆位移即可。
\(O(n\log^2 n)\)。
Code
vec Mul(int l,int r){
if(l==r){
vec ret(2);
ret[0]=1;
ret[1]=P-l;
return ret;
}
int mid=l+r>>1;
vec f=Mul(l,mid),g=Mul(mid+1,r);
vec ret=mul(f,g,r-l+2);
ret.resize(r-l+2);
return ret;
}
int main(){
IO>>n>>k;
prep(n<<1);
vec f=Mul(1,k),g,ret(n+1);
getinv(f,g,n+1);
for(int i=k;i<=n;i++)ret[i]=g[i-k];
for(int i=0;i<=n;i++)IO<<ret[i]<<' ';
return 0;
}
二.一类组合变换及相关计数问题
部分参考了 rqy 的图计数课件。
2.1 数列的组合变换
考虑构造这样一个模型:
- 如果一个装有 \(i\) 个球的盒子有 \(a_i\) 种涂色方式,求把 \(n\) 个球放到若干个盒子里的方案数为 \(b_n\)。
- 注意装有的球的个数不同的两个盒子涂的颜色也是不同的。
下面来细化一下具体的规则,一般用三个字母表示。
首先是盒子顺序的问题:
- A. 线性(ordered):盒子从左到右排成一行;
- B. 线性,可翻转(reversible):盒子排成一行,但翻转视为相同的;
- C. 循环(necklace):盒子排成一圈。
- D. 循环,可翻转(bracelet),盒子排成一圈,翻转视为相同;
- E. 无序(unordered):盒子无序,即任意重排都视为相同。
然后是盒子区分的问题:
- F. 大小(size):任意两个盒子都能根据大小(指球的个数,下同)来区分,即大小两两不同;
- G. 元素(element):任意两个盒子都能由大小和颜色区分,即不存在两个盒子大小和颜色都相同。
- H. 具体信息(identity):任意两个盒子都能根据大小、颜色和位置区分(具体见下);
- I. 无限制(indistinct):没有这一类限制。
规则 H 的意思是,不存在两个盒子的地位是等价的,也就是说重排后的序列与原序列不同。比如如果序列是线性、可翻转的(B),那么 H 就是说翻转后的序列不能与原来相同,C、D 同理。
然后是球如何区分的问题:
- J. 有标号(labeled):球有标号。
- K. 无标号(unlabeled):球没有标号。
容易知道,AHX 和 AIX 等价,EHX 和 EGX 等价,所以 AHX 和 EHX 都是没有意义的。
这三个规则各取一个,就可以得到一个组合变换。除去前面列举的四个无意义的变换,一共有 36 个不同的变换。
举个例子,BGJ 就是说,这些盒子排成一排,可以翻转,任意两个盒子都要不同,球有标号。
另外,\(\operatorname{XXX}_k\) 表示变换 XXX ,而且有恰好 \(k\) 个箱子。
下面列举一些广为人知的组合变换。
以下除特殊标注外,设 \(A(x)\) 为 \(\{a_i\}\) 的 OGF,\(B(x)\) 为 \(\{b_i\}\) 的 OGF。
2.1.1 AIK 变换
即盒子有序,球无标号,没有额外限制。
易知 \(k\) 个箱子时的生成函数应该是 \(A^k\),所以可得
这个变换被称为 INVERT。
由此容易知道,\(\operatorname{AIK}_k(A)=A^k\)。
2.1.2 EGK 变换
即盒子无序,球无标号,相同大小颜色的盒子至多一个。
容易知道这其实是一个 01 背包(注意不同颜色盒子不同),所以
这个变换叫做 WEIGHT。
\(\operatorname{EGK}_k\) 目前除暴力外无其余式子。
2.1.3 EIJ 变换
即盒子无序,球有标号,没有额外限制。
取 \(A(x)\) 为 \(\{a_i\}\) 的 EGF,\(B(x)\) 同理,可得 \(k\) 个箱子时的 EGF 为 \(\dfrac{A^k}{k!}\),所以
这个变换叫做 EXP。
由此容易知道,\(\operatorname{EIJ}_k(A)=\dfrac{A^k}{k!}\)。
2.1.4 EIK 变换
即盒子无序,球无标号,没有额外限制。
类似 EGK,可知这其实就是一个完全背包。
这个变换叫做 EULER。
\(\operatorname{EIK}_k\) 目前无式子。
这里补充一个 EULER 变换的逆变换的 \(O(n\log n)\) 计算方法:显然 \(\ln A\) 的系数其实就是 \(B\) 的系数和 \(\frac{1}{x}\) 的系数的狄利克雷卷积,考虑设
则显然有
预处理约数后直接递推就完了。
2.2 计数例题
2.2.1 有标号连通图计数
容易知道有标号图计数就是 \(2^\binom{n}{2}\),因此只要对它求一下 EIJ 的逆(即 \(\ln\))就完了。
复杂度 \(O(n\log n)\)。
2.2.2 无标号图计数
不会,似乎不可做?
2.2.3 无标号连通图计数
前面那题的 EIK 逆变换。
2.2.4 有标号 DAG 计数
设 \(f(i)\) 表示 \(i\) 个点的 DAG 个数,考虑枚举入度为 \(0\) 的点的个数,剩余点构成 DAG,可得:
组合数用 egf,2 的幂用 Bluestein,得到一个卷积式,完事。
复杂度 \(O(n\log n)\)。
2.2.5 有标号弱联通 DAG 计数
直接对上面那个式子求一个 EIJ 就可以了。
2.2.6 边双计数
两种做法:用拉反和不用。
不用拉反的做法:任取一个无向图,设 \(S\) 为全部割边集合,则最后的图一定是由若干个边双由 \(S\) 中的边连成的。
先枚举连通块,设大小为 \(a_1\sim a_n\),则取 \(S\) 的方案数为 \(n^{m-2}\prod a_i\),乘上容斥系数就是 \(-\frac{1}{n^2}\prod (-na_i)\)。
那么我们设上面的有标号连通图的 EGF 为 \(H\),那么设 \(G\) 满足 \(G_i=-niH_i\),答案就是 \([x^n]-\frac{n!}{n^2}\exp G\)。
用拉反的做法:考虑有根连通无向图的 EGF 为 \(D\),有根边双连通图的 EGF 为 \(B\)。
\(D\) 容易直接写出,考虑怎么用 \(B\) 来表示 \(D\)。
设根所在边双的大小为 \(n\),EGF 为 \(\frac{b_nx^n}{n!}\)。对于他相邻的边,每条边都挂着一个连通无向图,所以可得
设 \(F=x\exp D\),可得 \(D=B(F)\),所以 \(D(F^{-1})=B\),由拉反可得
复杂度都是 \(O(n\log n)\)。
2.2.7 点双计数
与上题类似,考虑包括根节点的全部极大点双分量,那么将根节点删去后剩余的连通块个数就是点双分量的个数。注意到每一组点双都可以在任意一点上插上一个以其为根的无向连通图,且不影响包含这个点的任意点双的大小。
所以可得一个连通块的方案数就是:
其中 \(F\) 是有根无向连通图的 EGF,\(G\) 是点双的 EGF。
所以有
其中 \(H=\ln \dfrac{F}{x}\)。
拉反可得:
复杂度为 \(O(n\log n)\)。
2.2.8 括号序列计数
设 \(F\) 是 \(\texttt{(}S\texttt{)}\) 形式的合法括号序列的生成函数,那么可以得到
那么我们需要求的括号序列的生成函数就是
然后这就是卡特兰数。
2.2.9 超级括号序列计数
题解已隐藏