其他分享
首页 > 其他分享> > arc106f Figures

arc106f Figures

作者:互联网

有 \(n\) 个点 , 第 \(i\) 个点上有 \(d_i\) 个插孔 ,每个插孔都是独一无二的,每条边可以连接任意两个点上的两个插孔,问有多少种不同的连边方法可以连出一棵树。
\(1\leq n\leq 2\cdot 10^5,1\leq d_i<998244353\)

首先,无根树,考虑 prufer 序列 .

考虑确定每个点的度数 \(a_i\) ,方案书是

\[(n-2)!\sum\limits_{a_1+a_2+\cdots+a_{n-1}=2n-2}\prod \frac{d_i^{\underline{a_i}}}{(a_i-1)!} \]

这个式子看上去就非常不可做,考虑引入生成函数 .

\[\begin{align} f(x)&=\sum_{i=1}^{d_x} \frac{d_x^{\underline{i}}}{(i-1)!}x^i \end{align} \]

答案如下,看上去很有前途的样子 .

\[(n-2)![2n-2]\prod f(i) \]

考虑化简上面这个式子,

\[\begin{align} f(x)&=\sum_{i=1}^{d_x} \frac{d_x^{\underline{i}}}{(i-1)!}x^i\\ &=\sum_{i=1}^{d_x}\frac{d_x!}{(i-1)!(d_x-i)!}x^i\\ \end{align} \]

发现这个差一点就可以凑成组合数了 . 此时,考虑把下表同意减一 . 此时,从 \(x^0\) 到 \(x^{d_x-1}\) 才符合比较标准的多项式 . 于是有

\[\begin{align} f(x)&=\sum\limits_{i=0}^{d_x-1}\frac{d_x^{\underline{i+1}}}{i!} x^i\\ &=\sum\limits_{i=0}^{d_x-1}\frac{d_x(d_x-1)^{\underline{i-1}}}{i!}x^i\\ &=d_x\sum\limits_{i=0}^{d_x-1}\frac{(d_x-1)!}{i!(d_x-i-1)!}x^i\\ &=d_x\sum\limits_{i=0}^{d_x-1}\dbinom{d_x-1}{i}x^i\\ &=d_x(x+1)^{d_x-1} \end{align} \]

此时,就得到了一个非常非常棒的式子 . 接着化简答案 .

\[\begin{align} ans&=(n-2)![n-2]\prod{f(x)}\\ &=(n-2)![n-2]\prod{d_x(x+1)^{d_x-1}}\\ &=(n-2)![n-2](x+1)^{\sum d_x-1}\prod{d_x}\\ &=(n-2)!\dbinom{\sum{d_x-1}}{n-2}\prod{d_x}\\ &=(n-2)!(\sum d_x-1)!\prod d_x \end{align} \]

最后划得一个很简短的式子,真的很神奇 .

用最后一个式子和倒数第二个式子都能算出答案 ,我用的是倒数第二个 .

感觉好奇妙 ( 然而没有做出来 ) ,可能是我第一次想推柿子的题目罢 .

时间复杂度 : \(O(n\log d)\)

空间复杂度 : \(O(n)\)

code
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n;
int d[200010]; 
inline int ksm(int x,int k){
	if(k==0)return 1;
	int res=ksm(x,k>>1);
	res=1ll*res*res%mod;
	if(k&1)res=1ll*res*x%mod;
	return res;
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=0;i<n;i++)cin>>d[i];
	int ans=1;
	for(int i=1;i<=n-2;i++)ans=1ll*ans*i%mod;
	for(int i=0;i<n;i++)ans=1ll*ans*d[i]%mod;
	int sum=0;
	for(int i=0;i<n;i++)sum=(d[i]-1+sum)%mod;
	for(int i=0;i<n-2;i++)ans=1ll*(sum-i+mod)%mod*ans%mod;
	for(int i=1;i<=n-2;i++)ans=1ll*ans*ksm(i,mod-2)%mod;
	cout<<ans<<endl;
	return 0;
}
/*inline? ll or int? size? min max?*/

标签:frac,int,res,sum,arc106f,Figures,prod,align
来源: https://www.cnblogs.com/suadwm/p/15674224.html