[题解][YZOJ7031] 计树

复习?

题目大意#

给出一个长度为 n 的排列,要求构建一棵 n 个节点的有标号树,满足若存在边 (i,j) 则存在边 (pi,pj)

求构建树的方案数。

n3×105,模数为 998244353

解题思路#

首先对于这种 ipi 相对应的题目,不妨先把置换环提出来,然后考虑题目的条件实际是要干什么。

于是不难意识到,若 x,y 连边,则要在两者所在的环上依次连边,那么现在需要考虑是否所有的连边都合法。

x,y 所在的环长度分别为 n,m (nm),根据手玩和置换的一些特性,可以发现:

  • m|n
  • n 只能和唯一一个大小为 m 连边。

hint:非法连边的情况都是出现环。

此时环与环之间的关系,实际上也就是一个树的关系,大小为 n 的环,其父亲一定是一个大小为 n 的因数的环。

故计数时,不妨枚举 n,然后考虑其与父亲的连边方案,那么对于某一个 n,其方案应对是:

i=1cntn(cntn1i1)ncntni×cntncntni×vali

首先考虑 n 这一层内的环相互连边,枚举连出来 i 棵树,第一部分即 cntn 个点,形成 i 棵树的森林的方案树

(考虑一个虚拟根节点,然后 prufer 序列计算)。

然后要考虑的就是,某两个环之间连边,方案数是多少,不难发现是两个环中较小的那个的大小。

第二部分即同层的环之间的连的边的选取方案数。

第三部分是 i 棵树的根连向较小的层连边的边的选取的方案数 (val=m|nmcntm)。

做到这里,我们其实还有一个问题没有考虑,一棵树,除了没有环,还应当保证连通。

如果最小的环大小为 1,那么只要把这些点连成一棵无根树即可。

如果最小的环大小为 2,那么其实要连成一棵有根树,为什么呢,因为仅仅按照环间连边的话,最后还是会有两棵树,所以要选择一个大小为 2 的环进行环内连边,使其连通。

看到这里,不知道有没有意识到之前都没有提及环内连边,原因是>2 的环,出现环内连边后,最终将因为无法和小于等于自己的其他环连边 (会成环),而最终无法连通,于是没有合法方案。

int main(){
	read(n), prep(n);
	lfor(i, 1, n) read(p[i]), G[p[i]].pb(i), G[i].pb(p[i]);
	lfor(i, 1, n) if(!vis[i]) dcnt = 0, dfs(i), ++c[dcnt];
	rfor(i, n, 1) if(c[i]) a[++m] = {i, c[i]};
	int Ans = 1;
	lfor(i, 1, m - 1){
		int sqr = sqrt(a[i].fi), val = mod - 1LL * a[i].fi * c[a[i].fi] % mod;
		lfor(j, 1, sqr) if(a[i].fi % j == 0){
			MOD(val += 1LL * j * c[j] % mod - mod);
			MOD(val += 1LL * (a[i].fi / j) * c[a[i].fi / j] % mod - mod); 
		}
		if(sqr * sqr == a[i].fi) MOD(val -= 1LL * sqr * c[sqr] % mod - mod);
		int res = 0;
		lfor(j, 1, a[i].se){
			int sum = 1LL * C(a[i].se - 1, j - 1) * qpow(a[i].se, a[i].se - j) % mod;
			sum = 1LL * sum * qpow(val, j) % mod;
			sum = 1LL * sum * qpow(a[i].fi, a[i].se - j) % mod;
			MOD(res += sum - mod);
		}
		Ans = 1LL * Ans * res % mod;
	}
	if(a[m].fi == 1){
		if(a[m].se > 1) Ans = 1LL * Ans * qpow(a[m].se, a[m].se - 2) % mod;
	}else if(a[m].fi == 2){
		Ans = 1LL * Ans * qpow(a[m].se, a[m].se - 1) % mod * qpow(2, a[m].se - 1) % mod;
	}else Ans = 0;
	cout << Ans << endl;
	return 0;
}
posted @   IrisT  阅读(96)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示
主题色彩