Description
Solution
题目所求为$sum_{i=0}^{n-1} i2^ih_i$,其中$h_i$表示恰好有$i$条特殊边的方案数
设$g_i$为钦定有$i$条特殊边后随意连边的方案数,那么就有
$$g_i=sum_{j=i}^{n-1} inom{j}{i} h_i$$
再设$f_i$为图中钦定有$i$个连通块的方案数,即$f_i=g_{n-i}$,有
egin{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
ight ) ^i
end{align}
又因为
egin{align}
frac{1}{(1-x)^n}&=(1+x+x^2+cdots)^n\
&=sum _{jgeq 0}inom{j+n-1}{n-1}x^j
end{align}
发现$f_i$中的式子与上式中$n=2$的情况类似,于是
$$ sum _{j geq 0}jx^j=frac{x}{(1-x)^2} $$
那么
egin{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}inom{j+2i-1}{2i-1}x^j \
&=n^{i-2}inom{n+i-1}{2i-1}
end{align}
由二项式反演得
$$h_i=sum _{j=1}^{n-1} inom{j}{i} (-1)^{j-i}f_{n-j}$$
所以
egin{align}
ans&=sum _{i=0}^{n-1}i2^isum _{j=1}^{n-1}inom{j}{i}(-1)^{j-i}f_{n-j}\
&=sum _{j=0}^{n-1}f_{n-j}sum _{i=0}^ji2^iinom{j}{i}(-1)^{j-i}
end{align}
后面有点像二项式定理,尝试求下式
egin{align}
&sum_{i=0}^n ia^ib^{n-i}inom{n}{i} \
=&n!sum_{i=0}^nifrac{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}$
egin{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}
那么
egin{align}
ans&=sum_{i=0}^{n-1}2if_{n-i}\
&=sum _{i=0}^{n-1}2in^{n-i-2}inom{2n-i-1}{i}
end{align}
可以$O(n)$求解
#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 ",(ans+2*(n-1))%mod); return 0; }