[MtOI2018] 情侣?给我烧了!(加强版)
\(\text{Problem}:\)[MtOI2018]情侣?给我烧了!(加强版)
\(\text{Solution}:\)
前置内容:[MtOI2018] 情侣?给我烧了!
现在考虑继续推导 \(f\),有:
\[\begin{aligned}
f_{k}&=\frac{n!n!\cdot 2^{k}}{k!}\sum\limits_{i=0}^{n-k}(-1)^{i}\frac{1}{i!(n-k-i)!(n-k-i)!}\cdot 2^{i}\cdot (2n-2k-2i)!\\
&=\frac{n!n!\cdot 2^{k}}{k!}\sum\limits_{i=0}^{n-k}(-1)^{i}\binom{2n-2k-2i}{n-k-i}\frac{2^{i}}{i!}\\
&=\frac{n!n!\cdot 2^{k}}{k!}\cdot h_{n-k}
\end{aligned}
\]
设 \(H(x)\) 为序列 \(h_{i}\) 的 \(\text{OGF}\)。发现 \(h_{i}\) 可以表现为卷积形式,有:
\[\begin{aligned}
H(x)&=\sum\limits_{i=0}^{\infty}x_{i}\sum\limits_{j=0}^{i}(-1)^{j}\binom{2i-2j}{i-j}\frac{2^{j}}{j!}\\
&=\sum\limits_{i=0}^{\infty}\sum\limits_{j=0}^{i}\left((-1)^{j}\cdot\frac{2^{j}}{j!}\cdot x_{j}\right)\left(\binom{2i-2j}{i-j}x_{i-j}\right)\\
F(x)&=\sum\limits_{i=0}^{\infty}\frac{(-2)^{i}}{i!}x^{i}=e^{-2i}\\
G(x)&=\sum\limits_{i=0}^{\infty}\binom{2i}{i}x^{i}\\
H(x)&=F(x)G(x)
\end{aligned}
\]
现在尝试求出 \(G(x)\) 的封闭形式。考虑变换 \(\binom{2i}{i}\),有:
\[\begin{aligned}
\binom{2i}{i}&=\frac{2i(2i-1)(2i-2)\cdot\cdot\cdot 1}{(i(i-1)(i-2)\cdot\cdot\cdot 1)^{2}}\\
&=\frac{(2i-1)(2i-3)\cdot\cdot\cdot 3\cdot 1}{i(i-1)(i-2)\cdot\cdot\cdot 1}\cdot 2^{i}\\
&=\frac{(i-\frac{1}{2})(i-\frac{3}{2})\cdot\cdot\cdot\frac{3}{2}\cdot\frac{1}{2}}{i(i-1)(i-2)\cdot\cdot\cdot 1}\cdot 4^{i}\\
&=\binom{i-\frac{1}{2}}{i}\cdot 4^{i}
\end{aligned}
\]
将其代入到 \(G(x)\) 中,有:
\[\begin{aligned}
G(x)&=\sum\limits_{i=0}^{\infty}\binom{i-\frac{1}{2}}{i}\cdot 4^{i}\cdot x^{i}\\
&=\sum\limits_{i=0}^{\infty}(-1)^{i}\binom{-\frac{1}{2}}{i}\cdot (4x)^{i}\\
&=(1-4x)^{-\frac{1}{2}}\\
H(x)&=\frac{e^{-2x}}{\sqrt{1-4x}}
\end{aligned}
\]
考虑对 \(H\) 求导,有:
\[H'(x)=\frac{8x e^{-2x}}{(1-4x)^{\frac{3}{2}}}=\frac{8x H(x)}{1-4x}
\]
两边同乘 \((1-4x)\),暴力展开每一项,得到:
\[(i+1)h_{i+1}=8h_{i-1}+4ih_{i}
\]
直接递推即可。总时间复杂度 \(O(n+T)\)。
\(\text{Code}:\)
#include <bits/stdc++.h>
#pragma GCC optimize(3)
//#define int long long
#define ri register
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define is insert
#define es erase
#define vi vector<int>
#define vpi vector<pair<int,int>>
using namespace std; const int N=5000010, Mod=998244353;
inline int read()
{
int s=0, w=1; ri char ch=getchar();
while(ch<'0'||ch>'9') { if(ch=='-') w=-1; ch=getchar(); }
while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
return s*w;
}
int fac[N+5],inv[N+5],pw[N+5],h[N+5];
inline int ksc(int x,int p) { int res=1; for(;p;p>>=1, x=1ll*x*x%Mod) if(p&1) res=1ll*res*x%Mod; return res; }
inline void Init()
{
fac[0]=1;
for(ri int i=1;i<=N;i++) fac[i]=1ll*fac[i-1]*i%Mod;
inv[N]=ksc(fac[N],Mod-2);
for(ri int i=N;i;i--) inv[i-1]=1ll*inv[i]*i%Mod;
pw[0]=1;
for(ri int i=1;i<=N;i++) pw[i]=(pw[i-1]<<1)%Mod;
h[0]=1;
for(ri int i=2;i<=N;i++) h[i]=(8ll*h[i-2]%Mod+4ll*(i-1)*h[i-1]%Mod)%Mod, h[i]=1ll*h[i]*inv[i]%Mod*fac[i-1]%Mod;
}
signed main()
{
Init();
for(ri int T=read();T;T--)
{
int n,k;
n=read(), k=read();
printf("%d\n",1ll*fac[n]*fac[n]%Mod*pw[k]%Mod*inv[k]%Mod*h[n-k]%Mod)%Mod;
}
return 0;
}
后记:本题也可以从错排的思路入手,得出递推式较为自然。两种方法都是组合计数中的常用技巧,要熟练掌握。
夜畔流离回,暗叹永无殿。
独隐万花翠,空寂亦难迁。
千秋孰能为,明灭常久见。
但得心未碎,踏遍九重天。