P5825 排列计数

题目

直接无脑生成函数。

题目要求升高数。

设 \(g_{i,j}\) 表示排列长度 i,升高为 j 的方案数。

考虑最大元素的位置所产生的贡献可以得到。

\[g_{i,j}= \begin{cases} 1\quad i=0,j=0\\ (i-j)g_{i-1,j-1}+(j+1)g_{i-1,j}\quad 0\le j<i \\ 0\quad \text{otherwise} \end{cases} \]

设 \(G(x,y)=\sum_{i=0,j=0}g_{i,j}\frac{x^i}{i!}y^j\)。

\[G=\sum_{i=0,j=0}g_{i,j}\frac{x^i}{i!}y^j\\ \frac{\partial G}{\partial x}=\sum_{i=0,j=0}[ (i+1-j)g_{i,j-1}+(j+1)g_{i,j}]\frac{x^i}{i!}y^j\\ \frac{\partial G}{\partial x}=\sum_{i=0,j=0}(i+1-j)g_{i,j-1}\frac{x^i}{i!}y^j +y\frac{\partial G}{\partial y}+G\\ \frac{\partial G}{\partial x}=\sum_{i=0,j=0}(i-j)g_{i,j}\frac{x^i}{i!}y^{j+1} +y\frac{\partial G}{\partial y}+G\\ \frac{\partial G}{\partial x}=y(x\frac{\partial G}{\partial x}-y\frac{\partial G}{\partial y})+y\frac{\partial G}{\partial y}+G\\ (1-xy)\frac{\partial G}{\partial x}+(y^2-y)\frac{\partial G}{\partial y}=G\\ \]

这是一个一阶变系数线性齐次偏微分方程不觉得名字很好玩吗。

会的 dalao 可以直接自行进行求解了。

感谢王老师愿意教我。

一阶变系数线性齐次偏微分方程 我会讲的通俗易懂点,想要看严谨的请移步。

注意我们设 \(x,y\in(0,1)\)。

我们考虑引入参数 \(t\)(特征线法)。

而 \(G\) 对 \(t\) 的全导数有。

\[\frac{dG}{dt}=\frac{dx}{dt}G_x+\frac{dy}{dt}G_y \]

发现这个和我们的方程很像,于是可以列出。

\[\begin{cases} \frac{dx}{dt}=1-xy\\ \frac{dy}{dt}=y^2-y\\ \frac{dG}{dt}=G\\ \end{cases} \]

然后我们两两消掉。

\[\frac{dy}{dG}=\frac{y(y-1)}{G}\\ (\frac{1}{y-1}-\frac{1}{y})dy=\frac{1}{G}dG\\ \ln|G|=\ln|y-1|-\ln|y|+C\\ \ln G=\ln\frac{1-y}{y}+C\\ G=\frac{1-y}{y}e^C\\ C_1=\frac{Gy}{1-y}\\ \frac{dx}{dy}=\frac{1-xy}{y(y-1)}\\ \frac{dx}{dy}+\frac{x}{y-1}=\frac{1}{y(y-1)}\\ \mu =e^{\int \frac{1}{y-1}dy}=|y-1|=1-y\\ \frac{dx}{dy}(1-y)-x=-\frac{1}{y}\\ \frac{d}{dy}(x(1-y))=-\frac{1}{y}\\ x(1-y)=-\ln y+C\\ C_2=x(1-y)+\ln y\\ \]

求出两个常数,那么它们一定存在某种关系 \(C_1=\phi(C_2)\)。

然后我们把边界值代入求出 \(\phi\)。

\[C_1=\frac{Gy}{1-y}\\ C_2=x(1-y)+\ln y\\ G(0,y)=1\\ \frac{y}{1-y}=\phi(\ln y)\\ s=\ln y\\ \phi(s)=\frac{e^s}{1-e^s}=\frac{1}{e^{-s}-1}\\ \frac{Gy}{1-y}=\frac{1}{e^{-(x(1-y)+\ln y)}-1}\\ G=\frac{1-y}{e^{-x(1-y)}-y}=\frac{(1-y)e^{x(1-y)}}{1-ye^{x(1-y)}}\\ \]

这样我们就求出 \(G\) 了。

然后可以求出 \(g_{i,j}\)。

\[\begin{aligned} G(x,y)&=\frac{(1-y)e^{x(1-y)}}{1-ye^{x(1-y)}}\\ &=(1-y)e^{x(1-y)}\sum_{i=0}(ye^{x(1-y)})^i\\ &=(1-y)\sum_{j=0}y^j e^{x(1-y)(j+1)}\\ &=(1-y)\sum_{j=0}y^j \sum_{i=0}((1-y)(j+1))^i\frac{x^i}{i!}\\ &=\sum_{i=0}\frac{x^i}{i!}(1-y)^{i+1}\sum_{j=0}y^j(j+1)^i \\ &=\sum_{i=0}\frac{x^i}{i!}\sum_{s=0}^{i+1}(-1)^{s}\binom{i+1}{s}y^s\sum_{j=0}y^j(j+1)^i \\ &=\sum_{i=0}\frac{x^i}{i!}\sum_{j=0}y^j\sum_{s=0}^{j}(-1)^s\binom{i+1}{s}(j-s+1)^i \\ \end{aligned} \\ g_{n,m}=[\frac{x^n}{n!}y^m]G=\sum_{s=0}^{m}(-1)^s\binom{n+1}{s}(m-s+1)^n \]

最后直接卷积一下即可,时间复杂度 \(O(N\log N)\)。

code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using i128 = __int128;
#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,r,l) for(int i=(r);i>=(l);--i)
const int N=(1<<20)+5;
const ll mod=998244353,G=3,IG=332748118;
int n,r[N];
ll fac[N],inv[N];
ll C(int n,int m){return n<m||m<0?0ll:fac[n]*inv[m]%mod*inv[n-m]%mod;}
ll pom(ll a,ll b){ll res=1;for(;b;b>>=1,a=a*a%mod) if(b&1)res=res*a%mod;return res;}
void NTT(ll *a,int op,int lim){
	rep(i,0,lim-1)if(i<r[i])swap(a[i],a[r[i]]);
	for(int mid=1;mid<lim;mid<<=1){
		ll wn=pom(op==1?G:IG,(mod-1)/(mid<<1)),w=1;
		for(int j=0;j<lim;j+=(mid<<1),w=1)
			for(int k=j;k<j+mid;++k,w=(ll)w*wn%mod){
				ll x=a[k],y=a[k+mid]*w%mod;
				a[k]=(x+y)%mod,a[k+mid]=(x-y+mod)%mod;
			}
	}
	if(op==-1){
		ll in=pom(lim,mod-2);
		rep(i,0,lim-1)a[i]=a[i]*in%mod;
	}
}

void conv(ll *a,ll *b,int n,int m){
	int lim=1,_=0;
	while(lim<=n+m)lim<<=1,_++;
	rep(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<_-1);
	fill(a+n+1,a+lim,0);fill(b+m+1,b+lim,0);
	NTT(a,1,lim);NTT(b,1,lim);
	rep(i,0,lim-1)a[i]=a[i]*b[i]%mod;
	NTT(a,-1,lim);
}
ll a[N],b[N];
void solve(){
    cin>>n;
    rep(i,0,n+1)a[i]=(i&1)?mod-C(n+1,i):C(n+1,i);
    rep(i,0,n+1)b[i]=pom(i,n);
    conv(a,b,n+1,n+1);
    rep(i,1,n+1)cout<<a[i]<<" ";
}

int main(){
	cin.tie(0)->ios::sync_with_stdio(false);
	fac[0]=1;
    rep(i,1,N-1) fac[i]=fac[i-1]*i%mod;
    inv[N-1]=pom(fac[N-1],mod-2);
    per(i,N-2,0) inv[i]=inv[i+1]*(i+1)%mod;
	solve();
}
posted @ 2026-09-17 21:42  lzx0921  阅读(11)  评论(0)    收藏  举报