2021/01/29 模拟赛 交通网络
Description
Solution
题目所求为$\sum_{i=0}^{n-1} i2^ih_i$,其中$h_i$表示恰好有$i$条特殊边的方案数
设$g_i$为钦定有$i$条特殊边后随意连边的方案数,那么就有
$$g_i=\sum_{j=i}^{n-1} \binom{j}{i} h_i$$
再设$f_i$为图中钦定有$i$个连通块的方案数,即$f_i=g_{n-i}$,有
\begin{align}
f_i & = \sum_{a_1+a_2+ \cdots +a_i = n} n^{i-2} \prod_{j = 1}^i a_j\\
& =n^{i-2} \sum_{a_1+a_2+ \cdots +a_i = n} \prod_{j = 1}^i a_j\\
& =n^{i-2}[x^n]\prod_{k=1}^i \sum _{j \geq 0}jx^j\\
& =n^{i-2}[x^n]\left ( \sum _{j \geq 0}jx^j \right ) ^i
\end{align}
又因为
\begin{align}
\frac{1}{(1-x)^n}&=(1+x+x^2+\cdots)^n\\
&=\sum _{j\geq 0}\binom{j+n-1}{n-1}x^j
\end{align}
发现$f_i$中的式子与上式中$n=2$的情况类似,于是
$$ \sum _{j \geq 0}jx^j=\frac{x}{(1-x)^2} $$
那么
\begin{align}
f_i &=n^{i-2} [x^n]\frac{x^i}{(1-x)^{2i}} \\
&=n^{i-2}[x^{n-i}]\frac{1}{(1-x)^{2i}} \\
&=n^{i-2}[x^{n-i}]\sum_{j \geq 0}\binom{j+2i-1}{2i-1}x^j \\
&=n^{i-2}\binom{n+i-1}{2i-1}
\end{align}
由二项式反演得
$$h_i=\sum _{j=1}^{n-1} \binom{j}{i} (-1)^{j-i}f_{n-j}$$
所以
\begin{align}
ans&=\sum _{i=0}^{n-1}i2^i\sum _{j=1}^{n-1}\binom{j}{i}(-1)^{j-i}f_{n-j}\\
&=\sum _{j=0}^{n-1}f_{n-j}\sum _{i=0}^ji2^i\binom{j}{i}(-1)^{j-i}
\end{align}
后面有点像二项式定理,尝试求下式
\begin{align}
&\sum_{i=0}^n ia^ib^{n-i}\binom{n}{i} \\
=&n!\sum_{i=0}^ni\frac{a^i}{i!}\frac{b^{n-i}}{(n-i)!} \\
=&n!\sum _{i=0}^n \frac{a^i}{(i-1)!}\frac{b^{n-i}}{(n-i)!}
\end{align}
求和内的前一个分式的EGF是$\frac{ax}{0!}+\frac{a^2x^2}{1!}+\cdots =ax·e^{ax} $
后一个分式的EGF是$e^{bx}$
\begin{align}
原式&=n! [x^n]ax·e^{ax}·e^{bx}\\
&=an![x^{n-1}]e^{(a+b)x}\\
&=an!\frac{(a+b)^{n-1}}{(n-1)!}\\
&=an(a+b)^{n-1}
\end{align}
那么
\begin{align}
ans&=\sum_{i=0}^{n-1}2if_{n-i}\\
&=\sum _{i=0}^{n-1}2in^{n-i-2}\binom{2n-i-1}{i}
\end{align}
可以$O(n)$求解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> using namespace std; long long ans,fac[1000005],inv[1000005],pw[500005],n; const long long mod=998244353; inline int read(){ int f=1,w=0; char ch=0; while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar(); return f*w; } long long ksm(long long a,long long p){ long long ret=1ll; while(p){ if(p&1)(ret*=a)%=mod; (a*=a)%=mod,p>>=1; } return ret; } inline long long C(int x,int y){{ if(y>x)return 0; return fac[x]*inv[y]%mod*inv[x-y]%mod;} } int main(){ freopen("traffic.in","r",stdin),freopen("traffic.out","w",stdout); fac[0]=pw[0]=1ll; for(int i=1;i<=1000000;i++)fac[i]=fac[i-1]*i%mod; inv[1000000]=ksm(fac[1000000],mod-2); for(int i=999999;~i;i--)inv[i]=inv[i+1]*(i+1)%mod; n=read(); for(int i=1;i<=500000;i++)pw[i]=pw[i-1]*n%mod; for(int i=0;i<n-1;i++)(ans+=pw[n-i-2]*C(2*n-i-1,i)%mod*2%mod*i%mod); printf("%lld\n",(ans+2*(n-1))%mod); return 0; }