社区讨论

64求调

P14254分割(divide)参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhj0wthu
此快照首次捕获于
2025/11/03 18:54
4 个月前
此快照最后确认于
2025/11/03 18:54
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long
#define pb push_back
const int N=1e6+5,P=998244353;
using namespace std;
struct st{
	int to,nxt;
}edge[N<<1];
int head[N],cnt,d[N],g[N],c[N];
vector < int > G[N];
inline void addedge(int x,int y){
	edge[++cnt].to=y;
	edge[cnt].nxt=head[x];
	head[x]=cnt;
}
inline void dfs(int x,int fa){
	G[d[x]].pb(x);
	g[x]=1;
	for (int i=head[x];i;i=edge[i].nxt){
		int v=edge[i].to;
		if (v==fa) continue;
		d[v]=d[x]+1;
		dfs(v,x);
		g[x]=max(g[x],g[v]+1);
	}
}
inline int mul(int x,int y){
	return x*y%P;
}
inline int qpow(int x,int k){
	int ret=1;
	while (k){
		if (k&1) ret=mul(ret,x);
		x=mul(x,x),k>>=1;
	}
	return ret;
}
inline int add(int x,int y){
	return x+y>=P?x+y-P:x+y;
}
inline int sub(int x,int y){
    return x-y<0?x-y+P:x-y;
}
inline bool cmp(int x,int y){
	return g[x]>g[y];
}
inline int A(int n,int k){
	if (n<k) return 0;
    return mul(c[n],qpow(c[n-k],P-2));
}
signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,k,ans=0;cin>>n>>k;
	for (int i=2;i<=n;i++){
		int x;cin>>x;
		addedge(x,i);
	} 
	d[1]=1;dfs(1,0);
    c[0]=1;
    for (int i=1;i<=n;i++) c[i]=mul(c[i-1],i);
	for (int x=1;x<=n;x++){
        if (G[x].size()<=k) continue;
        //cout<<x<<'\n';
		sort(G[x].begin(),G[x].end(),cmp);
        int lst=G[x].size()-1,w=G[x].size()-1;
        while (w>=0){
            //cout<<w<<'\n';
            while (lst>=0&&g[G[x][lst]]==g[G[x][w]]) lst--;
            for (int i=w;i>lst;i--){
            	if (lst+1==k-1) ans=add(ans,A(lst+1,lst+1));//cout<<ans<<' ';
            	if (w==G[x].size()||w!=k-1)ans=add(sub(A(w,k-1),A(lst+1,k-1)),ans);//cout<<ans<<' ';
    		}
            w=lst;
            //cout<<'\n';
        }
        //cout<<'\n';
	}
	cout<<ans;
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...