首页 > 其他 > 详细

BZOJ 1005 明明的烦恼

时间:2019-12-08 10:14:54      阅读:81      评论:0      收藏:0      [点我收藏+]

题面

题意

??给定树上一些节点的度数,对其他节点的度数不做要求,求可能的树的数量。

题解

??考虑求树所对应的 Prufer 序列的数量。Prufer 序列是一种能够完全表示标号无根树的信息的序列,它的构造及还原方式这里略去,只强调它的两个性质:

  • 根据 Prufer 序列的构造与还原方法,含 \(n\;(n\ge 2)\) 个点的标号无根树 \(T\) 与长度为 \(n-2\)\(p_i \in [1,n]\) 的序列 \(\{p_{n-2}\}\) 一一对应。

  • \(T\) 中标号为 \(i\) 的结点度数为 \(d_i\),则 \(i\)\(T\) 对应的 Prufer 序列中出现 \(d_i-1\) 次。

因此,题意相当于给定一些元素在长度为 \(n-2\) 的序列中出现的次数,求可能的序列总数。为每个被限定的数在还没被选中的位置中选择一些位置,最后在空位上随意填上没有被限制的数,用这个思路就可以求出答案。

Java 在高精度运算方面还是一如既往的方便。


代码

import java.util.*;
import java.math.*;

public class Main{
    public static BigInteger bigint(int n){
        return new BigInteger(String.valueOf(n));
    }
    public static BigInteger C(int n,int m){
        BigInteger ans=bigint(1);
        int i;
        for (i=0;i<m;i++)
            ans=ans.multiply(bigint(n-i)).divide(bigint(i+1));
        return ans;
    }
    public static BigInteger pow(int a,int b){
        BigInteger ans=bigint(1);
        BigInteger mul=bigint(a);
        while (b>0){
            if ((b&1)>0) ans=ans.multiply(mul);
            mul=mul.multiply(mul); b>>=1;
        }
        return ans;
    }
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        int i,n,m,k,cnt;
        BigInteger ans=bigint(1);
        n=in.nextInt(); m=n-2; cnt=0;
        if (n==1){
            k=in.nextInt();
            if (k!=0&&k!=-1) System.out.println("0");
            else System.out.println("1");
            return;
        }
        for (i=0;i<n;i++){
            k=in.nextInt();
            if (k==-1){
                cnt+=1; continue;
            }
            ans=ans.multiply(C(m,k-1));
            m-=k-1;
        }
        ans=ans.multiply(pow(cnt,m));
        System.out.println(ans);
        in.close();
    }
}

BZOJ 1005 明明的烦恼

原文:https://www.cnblogs.com/Kilo-5723/p/12004166.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!