CF1172B Nauuo and Circle题解 思维

Nauuo and Circle

传送门

Nauuo is a girl who loves drawing circles.

One day she has drawn a circle and wanted to draw a tree on it.

The tree is a connected undirected graph consisting of n n n nodes and n − 1 n-1 n1 edges. The nodes are numbered from 1 1 1 to n n n.

Nauuo wants to draw a tree on the circle, the nodes of the tree should be in n n n distinct points on the circle, and the edges should be straight without crossing each other.

“Without crossing each other” means that every two edges have no common point or the only common point is an endpoint of both edges.

Nauuo wants to draw the tree using a permutation of n n n elements. A permutation of n n n elements is a sequence of integers p 1 , p 2 , … , p n p_1,p_2,\ldots,p_n p1,p2,,pn in which every integer from 1 1 1 to n n n appears exactly once.

After a permutation is chosen Nauuo draws the i i i-th node in the p i p_i pi-th point on the circle, then draws the edges connecting the nodes.

The tree is given, Nauuo wants to know how many permutations are there so that the tree drawn satisfies the rule (the edges are straight without crossing each other). She only wants to know the answer modulo 998244353 998244353 998244353, can you help her?

It is obvious that whether a permutation is valid or not does not depend on which n n n points on the circle are chosen.

Input

The first line contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 2\le n\le 2\cdot 10^5 2n2105) — the number of nodes in the tree.

Each of the next n − 1 n-1 n1 lines contains two integers u u u and v v v ( 1 ≤ u , v ≤ n 1\le u,v\le n 1u,vn), denoting there is an edge between u u u and v v v.

It is guaranteed that the given edges form a tree.

Output

The output contains a single integer — the number of permutations suitable to draw the given tree on a circle satisfying the rule, modulo 998244353 998244353 998244353.

Examples

input #1

4
1 2
1 3
2 4

output #1

16

input #2

4
1 2
1 3
1 4

output #2

24

Note

Example 1

All valid permutations and their spanning trees are as follows.

Here is an example of invalid permutation: the edges ( 1 , 3 ) (1,3) (1,3) and ( 2 , 4 ) (2,4) (2,4) are crossed.

Example 2

Every permutation leads to a valid tree, so the answer is 4 ! = 24 4! = 24 4!=24.

题目翻译

诺诺是一个喜欢画圆的女孩。

有一天,她画了一个圆,想在上面画一棵树。

这棵树是一个连通的无向图,由 n n n 个节点和 n − 1 n-1 n1 条边组成。节点的编号从 1 1 1 n n n

诺诺想在圆上画一棵树,树的节点应位于圆上的 n n n 个点上。树的节点应位于圆上的 n n n 个点上,且边应是直的,互不交叉

"互不交叉"是指每两条边都没有公共点,或者唯一的公共点是两条边的端点。

诺诺想用 n n n 个元素的排列来画这棵树。 n n n 元素的排列是一个整数 p 1 , p 2 , … , p n p_1,p_2,\ldots,p_n p1,p2,,pn 序列,其中从 1 1 1 n n n 的每个整数都正好出现一次。

选择好排列组合后,诺诺在圆上的 p i p_i pi 点绘制 i i i 个节点,然后绘制连接节点的边。

树的边是给定的,诺诺想知道有多少种排列组合能使画出的树满足规则(边是直的,互不交叉),由于答案可能过大,故要取模,模数为 998244353 998244353 998244353 ,你能帮她吗?

显然,排列是否有效并不取决于选择圆上的 n n n 点。

输入格式

第一行包含一个整数 n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 2\le n\le 2\cdot 10^5 2n2105 ) - 树中的节点数。

接下来的每 n − 1 n-1 n1 行包含两个整数 u u u v v v 1 ≤ u , v ≤ n 1\le u,v\le n 1u,vn ),表示 u u u v v v 之间有一条边。

可以保证给定的边构成一棵树。

输出

输出包含一个整数 - 在符合规则的圆上绘制给定树所需的排列次数,模数为 998244353 998244353 998244353

提示

样例 1

所有有效的排列及其生成树如下。

下面是一个无效排列的例子:边 ( 1 , 3 ) (1,3) (1,3) ( 2 , 4 ) (2,4) (2,4) 相交。

样例 2

每种排列都会导致一棵有效的树,所以答案是 4 ! = 24 4! = 24 4!=24

注明

以上来自 C o d e F o r c e s ,翻译: D e e p L 、本人 以上来自CodeForces,翻译:DeepL、本人 以上来自CodeForces,翻译:DeepL、本人
觉得翻译不好的可以看洛谷翻译,洛谷此次翻译扳回一局。(洛谷,你牛牛牛)

解题思路

由题意可知,如果我们选择一个节点作为根节点,那么每个子树都必须位于圆上的连续弧中。所以我们可以用 DP 来解决这个问题。

f u f_u fu 是绘制子树 u u u 的方案数,先为每个子树选择一个位置,再是 u u u 本身,最后绘制子树,形式化的表示为:

f u = ( ∣ s o n ( u ) ∣ + [ u ≠ r o o t ] ) ! Π v ∈ s o n ( u ) f v f_u=(|son(u)|+[u\ne root])!\varPi_{v\in son(u)}f_v fu=(son(u)+[u=root])!Πvson(u)fv

但我们不需要确定根的位置,只假设根在圆上的某一点上,最后旋转圆,就可以得到答案为: n f r o o t nf_{root} nfroot .

最后,我们可以发现,我们不需要真正写 DP,因为答案就是 n n n 乘以每个节点度阶乘的乘积即:

A n s w e r = n Π i = 1 n d e g r e e [ i ] ! Answer=n\varPi_{i = 1}^ndegree[i]! Answer=nΠi=1ndegree[i]!

(不要问我为什么公式格式为什么如此抽象,是因为CSDN官方 K a T e X KaTeX KaTeX 公式显示制作不够完善的缘故。)

AC Code

#include<bits/stdc++.h>
using namespace std;
char buf[1048576], *p1, *p2;
template<typename T>inline void Super_Quick_Read(T &x) {
	bool f = 1;
	x = 0;
	char ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = !f;
		ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	}
	while (ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + (ch ^ 48), ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
	x = (f ? x : -x);
	return;
}
template<typename T>inline void Quick_Write(T x) {
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) Quick_Write(x / 10);
	putchar(x % 10 + '0');
	return;
}
int n;
long long D[200005], Answer = 1;
signed main() {
	Super_Quick_Read(n);
	for (register int i = 1; i <= n; ++i) D[i] = 1;
	for (register int i = 1, u, v; i < n; ++i)Super_Quick_Read(u), Super_Quick_Read(v), Answer = Answer * D[u] % 998244353 * D[v] % 998244353, ++D[u], ++D[v];
	Quick_Write(Answer * n % 998244353);
	return 0;
}

在此处呼吁:CSDN官方能不能完善一下你的 K e T e X KeTeX KeTeX 公式显示功能啊!!!

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值