专栏文章
AT_abc290_f 题解
AT_abc290_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minuwt7p
- 此快照首次捕获于
- 2025/12/02 08:45 3 个月前
- 此快照最后确认于
- 2025/12/02 08:45 3 个月前
先考虑一个序列的贡献,
一个序列 要满足存在对应的树的充要条件是 。
如何构造一棵直径最长的树?不妨令根节点度数为 ,每次可以在当前最深的点下接上一个非叶子节点,使最长链延长,再算上链的末尾的一个叶子节点,记序列中大于 的数的数量为 ,序列的贡献为 。
比如,对于序列 可以这样构造 。
CPP O
|
O
/ \
O O
/|\
O O O
|
O
于是可以枚举序列中大于 的数量 ,统计这样的序列的数量:
- 选择 个位置不为 ,方案数为 。
- 接下来需要满足 。只考虑原来大于 的数 ,即 ;需要求方程 的非负整数解数量,使用插板法,解的数量即为 。
由 (直接展开可证明),可知,
由 (由组合意义可证明),可知,
代码
CPP#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=998244353,N=2000000;
ll T,n,jc[N+6],ijc[N+6],ans;
inline ll qpow(ll a,ll b){
ll ret=1;
while(b){
if(b&1)ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
inline ll C(ll m,ll n){
if(m<0)return 0;
return 1ll*jc[n]*ijc[m]%mod*ijc[n-m]%mod;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
jc[0]=ijc[0]=1;
for(ll i=1;i<=N;i++)jc[i]=1ll*jc[i-1]*i%mod;
ijc[N]=qpow(jc[N],mod-2);
for(ll i=N-1;i>=1;i--)ijc[i]=1ll*ijc[i+1]*(i+1)%mod;
cin>>T;
while(T--){
cin>>n;
ans=1ll*(n*C(n-3,2*n-4)%mod+C(n-2,2*n-3))%mod;
cout<<ans<<"\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...