• 洛谷 P2290 [HNOI2004]树的计数


    题目描述

    输入输出格式

    输入格式:

     

    输入文件第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树不超过10^17个。

     

    输出格式:

     

    输出满足条件的树有多少棵。

     

    输入输出样例

    输入样例#1:
    4                     
    2 1 2 1
    
    输出样例#1:2

    题解:质因数分解+prufer数列
    以前学过prufer数列...全忘了....
    n个点的无根树对应的数列的长度为N-2,这说明一个n个点的无根树有n^(n-2)种
    树转prufer数列:
    将编号最小的叶子结点删掉,将与叶子结点相邻的点加入prufer数列
    prufer数列转树:
    对于集合G={1,2,3,..n}每次找出不在当前prufer数列里有的最小的元素x
    与prufer数列的首项连边,删除首项与x,直到剩下两个元素连边...
    结点i的度为x,那么i出现的次数为x-1
    对于i号点度数为d[i]的 无根树 树的种数有 (n - 2) ! / ( (d1 - 1)! (d2 - 1)! ……(dn - 1)!
    参考
    会爆long long 分解质因数


    代码:

    #include<iostream>
    #include<cstdio>
    #define over printf("0
    ")
    #define end return 0
    using namespace std;
    
    int n,x,ok,cnt[222];
    long long ans=1;
    
    void chai(int x,int y){
        for(int i=2;i*i<=x;i++){
            while(x%i==0){
                cnt[i]+=y;
                x/=i;
            }
        }
        if(x>1)cnt[x]+=y;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=2;i<=n-2;i++)chai(i,1);
        for(int i=1;i<=n;i++){
            scanf("%d",&x);ok+=x-1;
            if(!x&&n!=1){
                over; end;
            }
            for(int j=2;j<=x-1;j++)chai(j,-1);
        }
        if(ok!=n-2){
            over;end;
        }
        for(int i=2;i<=n;i++)
         for(int j=1;j<=cnt[i];j++)
          ans=ans*i;
        printf("%lld
    ",ans);
        return 0;
    }



  • 相关阅读:
    Linux_WEB访问控制示例(使用IPADDR类型)
    基于多IP地址Web服务
    基于多端口的Web服务
    基于多主机的Web服务
    Linux_WEB服务基础概念
    Linux_配置认证访问FTP服务
    Linux_配置匿名访问FTP服务
    Linux_部署日志服务器
    Linux_日志管理理论概述
    微信小程序 radio 单选框
  • 原文地址:https://www.cnblogs.com/zzyh/p/7659404.html
Copyright © 2020-2023  润新知