【题解】AT_abc290_f [ABC290F] Maximum Diameter

\(link\)
很难的蓝题

壹:构造最大直径

首先要考虑,当序列被确定之后,最大长度怎么计算

我们定义叶子节点为度数 \(X=1\) 的节点

有一个显然的情况,即把所有非叶子节点串式相连,然后把叶子节点插上面

设叶子节点有 \(K\) 个,此时最大长度 \(len=n-K+1\)

贰:计数

接下来我们要考虑的是如何计数

注意到,总度数 \(all\) 恒为 \(2*n-2\)

我们可以枚举 \(K\) ,然后把 \(all-K\) 分配给 \(n-K\) 个非叶子节点,再乘上 \(len\)

怎么计数把 \(all-K\) 分配给 \(n-K\) 个非叶子节点 的个数?

容易发现,\(all-K\) 是球个数,叶子节点是盒子个数,且球相同盒子不同,盒子不能为空

容易得到组合数 \(\binom{all-K-(n-K)-1}{n-K-1}=\binom{2*n-2-K-n+K-1}{n-K-1}=\binom{2*n-2-K-n+K-1}{n-K-1}=\binom{n-3}{n-K-1}\)

所以 \(\binom{n-3}{n-K-1}\) 即为答案

此时我们得到 \(ans=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*len=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K+1)\)

直接算是 \(O(n)\) 的,过不掉,不过我们可以考虑对 $ \sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K+1) $ 做变换

参:优化

两个常见组合公式

  • 吸收恒等式 \(k\binom{n}{k} = n\binom{n-1}{k-1}\)

  • 范德蒙德卷积 \(\sum_{i=0}^{k}\binom{n}{i}\binom{m}{k-i}=\binom{n+m}{k}\)

可以通过组合意义理解

\(ans=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K+1)\)

如果 \(n-K+1\) 可以转成 \(n-K-1+b\) 的形式,我们就可以用吸收恒等式优化

所以有 \(ans=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K-1+2)=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K-1)+2*\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}\)

左边单项式可以用 吸收恒等式 & 范德蒙德卷积 优化,右边单项式可以用 范德蒙德卷积 优化

得到 \(ans=\sum_{K=0}^{n}\binom{n}{K}\binom{n-4}{n-K-2}(n-3)+2\binom{2n-3}{n-1}=\binom{2n-4}{n-2}(n-3)+2\binom{2n-3}{n-1}\)

可以 \(O(1)\) 求出

完整来说

\(ans\)

\(=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K+1)\)

\(=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K-1+2)\)

\(=\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}*(n-K-1)+2*\sum_{k=0}^{n}\binom{n}{K}\binom{n-3}{n-K-1}\)

\(=\sum_{K=0}^{n}\binom{n}{K}\binom{n-4}{n-K-2}(n-3)+2\binom{2n-3}{n-1}\)

\(=\binom{2n-4}{n-2}(n-3)+2\binom{2n-3}{n-1}\)

肆:操作

\(\binom{2n-4}{n-2}(n-3)+2\binom{2n-3}{n-1}\)

\(\binom{n}{m}=\frac{n!}{m!(n-m)!}=n!*inv_{m!}*inv_{(n-m)!}\)

预处理阶乘,然后对于每个阶乘求逆元即可

线性求逆元公式:\(inv_{i}=inv_{i+1}*(i+1)%mod\)

时间复杂度 \(O(N+T)\)

伍:代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10,mod=998244353;
int fact[N],invf[N];
int ksm(int a,int b){
	int res=1;
	while(b){
		if(b&1){
			res=1LL*res*a%mod;
		}
		b>>=1;
		a=1LL*a*a%mod;
	}
	return res;
}
int inv(int x){
	return ksm(x,mod-2);
}
int C(int n,int m){
	return 1LL*fact[n]*invf[m]%mod*invf[n-m]%mod;
}
void solve(){
	int n;cin>>n;
	int ans=(1LL*C(2*n-4,n-2)*(n-3)%mod+2LL*C(2*n-3,n-1)%mod)%mod;
	if(n==2) ans=1;
	cout<<ans<<"\n";
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	fact[1]=1;
	for(int i=2;i<N;i++) fact[i]=1LL*fact[i-1]*i%mod;
	invf[N-1]=inv(fact[N-1]);
	for(int i=N-2;i>=1;i--) invf[i]=1LL*invf[i+1]*(i+1)%mod;
	int t;cin>>t;
	while(t--) solve();
	return 0;
}
posted @ 2026-03-27 21:29  Ming3398  阅读(4)  评论(0)    收藏  举报