zoukankan      html  css  js  c++  java
  • BZOJ 1430 小猴打架

    描述

    一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友。每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友。经过$N-1$次打架之后,整个森林的小猴都会成为好朋友。 现在的问题是,总共有多少种不同的打架过程。 比如当$N=3$时,就有{1-2,1-3}{1-2,2-3}{1-3,1-2}{1-3,2-3}{2-3,1-2}{2-3,1-3}六种不同的打架过程。

    题解

    问题 $=$ 求出$N$个有标号节点的树的个数 $ imes$ 连边的顺序。

    因为有 $N - 1$条边, 所以连边的顺序就是 $!(N-1)$。

    然后需要考虑的就是$N$个有标号节点的树的个数。

    我们首先要介绍prufer数列, 传送门

    prufer数列的构造方法 :找出度数为1 的节点中标号最小的点$x$,将与它相连的节$y$点录入数列, 再删除$x$。

    重复上述过程 , 直到只剩两个点。 这样构造出的数列与树唯一对应。 并且树也唯一对应数列。即数列的个数与树的个数相同。

    个数都为$N^{N-2}$

    最后的答案就是$N^{N - 2} imes !(N - 1)$

    代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 const int mod = 9999991;
     7 
     8 ll ans, n;
     9 
    10 ll fpow(ll a,ll p) {
    11     ll re = 1;
    12     for(; p; p >>= 1, a = a * a % mod) if(p &  1) re = re * a % mod;
    13     return re;
    14 }
    15 
    16 int main()
    17 {
    18     scanf("%lld", &n);
    19     ans = fpow(n, n - 2);
    20     for(int i = 1; i < n; ++i) ans = ans * i % mod;
    21     printf("%lld
    ", ans);
    22 }
    View Code
  • 相关阅读:
    spring cloud项目搭建
    获取iframe的window对象
    数学杂谈 #7
    [AGC023D] Go Home
    JOISC 2021 部分题解
    [NOI2017]泳池
    [NOI2016] 循环之美
    [NOI2016] 优秀的拆分
    [LG P3676]小清新数据结构题
    [ARC113F]Social Distance
  • 原文地址:https://www.cnblogs.com/cychester/p/9509247.html
Copyright © 2011-2022 走看看