BZOJ 1005 明明的烦恼 (组合数学)

题解:n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数。

则            

所以要求在n-2大小的数组中插入tot各序号,共有种插法;

在tot各序号排列中,插第一个节点的方法有种插法;

插第二个节点的方法有种插法;

.........

另外还有m各节点无度数限制,所以它们可任意排列在剩余的n-2-tot的空间中,排列方法总数为

根据乘法原理:

#include <cstdio>
#include <cmath>
int n,m,tot,i,j,d,down[1005],up[1005],p[1005],ans[10005];
void pi(int x,int a[]){
    for(int i=2;i<=x;i++)if(p[i]){
        int sum=i; while(sum<=x)a[i]+=x/sum,sum*=i;
    }
}
int main(){
    scanf("%d",&n);
    for(i=2;i<=1000;i++){
        for(j=2;j<=std::sqrt(i);j++)
        if(i%j==0)break;
        if(j>sqrt(i))p[i]=1;
    }
    for(i=1;i<=n;i++){
        scanf("%d",&d);
        if(d==-1){m++;continue;}
        if(d>1)pi(d-1,down);
        tot+=d-1;
    }
    pi(n-2-tot,down);pi(n-2,up);
    for(i=1;i<=1000;i++)up[i]-=down[i];
    ans[0]=1;
    for(i=1;i<=1000;i++)while(up[i]--){
        for(j=0;j<=10000;j++)ans[j]*=i;
        for(j=0;j<=10000;j++)if(ans[j]>9)ans[j+1]+=ans[j]/10,ans[j]%=10;
    }
    if(m)for(i=1;i<=n-2-tot;i++){
        for(j=0;j<=10000;j++)ans[j]*=m;
        for(j=0;j<=10000;j++)if(ans[j]>9)ans[j+1]+=ans[j]/10,ans[j]%=10;
    }
    if(tot>n-2||tot<n-2&&m==0)return puts("0"),0;
    i=10000; while(!ans[i])i--;
    while(~i)printf("%d",ans[i--]);
    return 0;
}

BZOJ 1005 明明的烦恼 (组合数学)

时间: 2024-10-11 16:26:43

BZOJ 1005 明明的烦恼 (组合数学)的相关文章

BZOJ 1005 明明的烦恼(Prufer数列)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1005 题意:给出一棵树的某些节点的度数d,有些未给.问满足这个条件的树有多少种? 思路:(1)Prufer 数列是无根树的一种数列.由一棵树可以构造出一个Prufer数列,Prufer数列可转化为原来的树.由树生成Prufer的一种简单方法是每次找出标 号最小的叶子节点将其父节点添加到Prufer数列并将该叶子节点删除.直到最后只剩下两个节点时结束.比如下面的这个树按照我们刚才的方法生

BZOJ 1005 明明的烦恼 Prufer序列+组合数学+高精度

题目大意:给定一棵n个节点的树的节点的度数,其中一些度数无限制,求可以生成多少种树 Prufer序列 把一棵树进行以下操作: 1.找到编号最小的叶节点,删除这个节点,然后与这个叶节点相连的点计入序列 2.反复进行1,直到这棵树只剩下两个节点时,退出 比如说这个图(来自度受百科) 最小叶节点为2,删除2,将3计入序列 最小叶节点为4,删除4,将5计入序列 最小叶节点为5,删除5,将1计入序列 最小叶节点为1,删除1,将3计入序列 图中只剩下两个节点,退出 于是得到这棵树的Prufer序列为{3,5

[BZOJ]1005 明明的烦恼(HNOI2008)

BZOJ的第一页果然还是很多裸题啊,小C陆续划水屯些板子. Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1. Output 一个整数,表示不同的满足要求的树的个数,无解输出0. Sample Input 3 1 -1 -1 Sampl

BZOJ 1005 明明的烦恼(prufer序列+高精度)

有一种东西叫树的prufer序列,一个树的与一个prufer序列是一一对应的关系. 设有m个度数确定的点,这些点的度为dee[i],那么每个点在prufer序列中出现了dee[i]-1次. 由排列组合可以推出公式.需要用高精度. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1100 using namespace std; typede

bzoj 1005: [HNOI2008]明明的烦恼(组合数学 purfer sequence)

1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 3945  Solved: 1563 [Submit][Status][Discuss] Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000), 接下来N行,第i+1行给出第i

【组合数学】【高精度】【prufer数列】【HNOI 2008】【bzoj 1005】明明的烦恼

1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3217 Solved: 1290 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣-- 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1 Output 一个

bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&amp;&amp;生成树计数

1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2248  Solved: 898[Submit][Status] Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度

BZOJ 1005: [HNOI2008]明明的烦恼 Purfer序列 大数

1005: [HNOI2008]明明的烦恼 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=1005 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为N(0 < N < = 1000),接下来N行,第i+1行

BZOJ 1005: [HNOI2008]明明的烦恼 Purfer数列

Purfer数列: http://www.cnblogs.com/zhj5chengfeng/p/3278557.html 题目大意 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为 1 到 N 的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 N(0<N<=1000),接下来 N 行,第 i+1 行给出第 i 个节点的度数 Di,如果对度数不要求,则输入 -1 Output 一个整数,表示不同的满足要求的树的个数,无解