社区讨论
64pts求调
P14254分割(divide)参与者 1已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhj135zk
- 此快照首次捕获于
- 2025/11/03 18:59 4 个月前
- 此快照最后确认于
- 2025/11/03 18:59 4 个月前
下面的代码尝试枚举深度 ,对深度为 的点按照子树深度从大到小排序,然后组合数学计算,但部分测试点 WA
CPP#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+1;
const ll mod = 998244353;
int n, k, p[N], h[N], d[N];
ll ans, inv[N], fact[N], facinv[N];
vector<int> e[N], f[N];
void dfs(int u){
h[u] = d[u];
for(auto v:e[u]){
d[v] = d[u] + 1;
dfs(v);
h[u] = max(h[u], h[v]);
}
f[d[u]].push_back(h[u]);
}
ll P(ll n, ll m){
if (n<0 || n<m) return 0;
return fact[n] * facinv[n-m] % mod;
}
int main(){
inv[1] = fact[0] = facinv[0] = 1;
for(ll i=2;i<N;i++) inv[i] = (mod-mod/i) * inv[mod%i] % mod;
for(ll i=1;i<N;i++){
fact[i] = fact[i-1] * i % mod;
facinv[i] = facinv[i-1] * inv[i] % mod;
}
cin>>n>>k;
for(int i=2;i<=n;i++){
cin>>p[i];
e[p[i]].push_back(i);
}
d[1] = 1;
dfs(1);
for(int i=1;i<=n;i++){
int sz = f[i].size();
if (sz <= k) continue;
sort(f[i].begin(), f[i].end(), greater<int>());
for(int r=0,l=0;r<sz;r++){
if (r+1==sz||f[i][r+1]!=f[i][r]){
if (r>=k){
ans += (P(r, k-1) - P(l, k-1) + mod) % mod * (r-l+1) % mod;
ans %= mod;
//cout << l <<' ' << r << ' '<<(P(r, k-1) - P(l, k-1) + mod) % mod * (r-l+1) % mod<<'\n';
}
if (l==k-1){
ans += fact[l] * (r-l+1) % mod;
ans %= mod;
}
l = r+1;
}
}
//cout << i << ' ' << ans << '\n';
}
cout << ans;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...