题解:AT_agc079_a [AGC079A] Tree Contraction Sequence
操作的过程太过复杂,考虑将题面简化。
发掘一下性质,如果想让一种删除方案合法,那么任何时刻对于每个结点
容易发现这个条件是充要的。现在对于每个
注意到对于
建图过程可以使用单调栈实现,问题转化为树上拓扑序计数,可以在
#include<bits/stdc++.h>
using namespace std;using ll=long long;const int N=250005,mod=998244353;
ll T,n,p[N],fa[N],f[N],sz[N],fac[N],inv[N];vector<int>G[N];
ll pw(ll n,ll m,ll p){ll res=1;while(m){if(m&1)res=res*n%p;n=n*n%p,m>>=1;}return res;}
void dfs(int u){sz[u]=f[u]=1;for(int v:G[u])dfs(v),sz[u]+=sz[v],f[u]=f[u]*f[v]%mod*inv[sz[v]]%mod;f[u]=f[u]*fac[sz[u]-1]%mod;}
main(){
fac[0]=1;for(int i=1;i<=250000;i++)fac[i]=fac[i-1]*i%mod;
inv[250000]=pw(fac[250000],mod-2,mod);for(int i=249999;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
for(cin>>T;T--;) {
vector<int>s;cin>>n;for(int i=1;i<=n;i++)G[i].clear();for(int i=2;i<=n;i++)cin>>p[i],fa[i]=1;
for(int i=n;i>=2;i--){while(s.size()&&p[s.back()]>=i)s.pop_back();if(s.size())fa[i]=s.back();s.push_back(i);}
for(int i=2;i<=n;i++)G[fa[i]].push_back(i);dfs(1);cout<<f[1]<<'\n';
}
}