[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
Sample Output
2
HINT
两棵树分别为1-2-3;1-3-2.
Solution
碰见这种没有知识储备脑子里都没有想法的题,考场上还是保佑自己碰到一些自己学过的算法吧。
讲这道题之前先来说说prufer编码是什么:
①prufer编码是树的一种表示形式,不同的编码与不同的树形态一一对应;
(不同的树形态指的是两棵树中至少有一条边连接的点不同)
②根据定理证明,n个点最多能构成(n-2)^n种不同的树形态。
(至于为什么是这个式子看看接下来prufer编码是如何构造的就知道了)
③构造方法:

如图所示,为一棵有6个结点的树,每次选出叶子节点中编号最小的一个,将与其相连的那个节点的标号加入数列,再将该叶子结点删去。直到树中剩下两个节点为止。
所以上图的树的prufer编码就是:5 3 1 5(依次删去2 4 3 1)。
显而易见,一棵节点数为n的树的prufer编码长度为n-2。
由于prufer编码的每一位都有可能是1~n,不同的prufer编码有(n-2)^n种。
所以根据第①条一一对应的性质,不同的树有(n-2)^n种。
利用prufer编码,我们可以轻易地解决这道题。
从prufer编码中,我们可以看出一棵树中所有点的度数,每个点的度数为它在prufer编码中出现的次数+1。
因此对于题目中规定度数的点,我们可以首先确定它们在prufer编码中的位置。
假设规定度数的点有p个,度数分别为a1、a2……ap。
那么把这p个点填进prufer编码的方案数是
。(排列组合、乘法原理瞎推)
那么prufer编码中剩下的空位有
个,未规定度数的节点有n-p个,所以方案数再乘上
即可。
由于答案没有取模,所以要用到高精度乘/除单精度。
题目中所说的无解情况有3种:
①
;
②
;
③
。
时间复杂度写得不是太糟都能过,注意高精度数的位数。
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define mod 1000000000
#define MS 354
using namespace std;
struct hp
{
int len; ll ar[MS];
friend hp operator/(const hp& a,int b)
{
register ll lt=;
register int i;
hp c;
memset(&c,,sizeof(c));
c.len=a.len;
for (i=a.len-;i>=;--i)
{
lt=lt*mod+a.ar[i];
c.ar[i]=lt/b; lt%=b;
}
if (!c.ar[c.len-]) --c.len;
return c;
}
friend hp operator*(const hp& a,int b)
{
register int i,j;
hp c;
memset(&c,,sizeof(c));
c.len=a.len;
for (i=;i<a.len;++i)
{
c.ar[i]+=a.ar[i]*b;
c.ar[i+]+=c.ar[i]/mod;
c.ar[i]%=mod;
}
if (c.ar[c.len]) ++c.len;
return c;
}
}sum;
int n,rn,uk; inline int read()
{
int n=,f=; char c=getchar();
while (c<'' || c>'') {if(c=='-')f=-; c=getchar();}
while (c>='' && c<='') {n=n*+c-''; c=getchar();}
return n*f;
} int main()
{
register int i,x;
sum.ar[]=; sum.len=;
n=read(); rn=n-;
for (i=;i<=rn;++i) sum=sum*i;
for (i=;i<=n;++i)
{
x=read()-;
if (x>) {if (rn>=x) {for (rn-=x;x>=;--x) sum=sum/x;} else return *printf("");}
else if (x==-) ++uk;
else return *printf("");
}
if (rn&&!uk) return *printf("");
for (i=;i<=rn;++i) sum=sum/i*uk;
printf("%lld",sum.ar[sum.len-]);
for (i=sum.len-;i>=;--i) printf("%09lld",sum.ar[i]);
}
Last Word
小C看到这道题的时候就觉得这肯定不是正常题,就是没有看过相关的东西死都做不出来的那种。
结果真的是这样。
[BZOJ]1005 明明的烦恼(HNOI2008)的更多相关文章
- [HNOI2008][bzoj 1005]明明的烦恼(prufer序列)
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7121 Solved: 2816[Submit][Stat ...
- BZOJ 1005 明明的烦恼
Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 ...
- BZOJ 1005 明明的烦恼 (组合数学)
题解:n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数. 则 所以要求在n-2大小的数组中插入tot各序号,共有种插法: 在tot各序号排列中,插第一个节点的 ...
- BZOJ 1005 明明的烦恼(prufer序列+高精度)
有一种东西叫树的prufer序列,一个树的与一个prufer序列是一一对应的关系. 设有m个度数确定的点,这些点的度为dee[i],那么每个点在prufer序列中出现了dee[i]-1次. 由排列组合 ...
- BZOJ 1005 明明的烦恼 Prufer序列+组合数学+高精度
题目大意:给定一棵n个节点的树的节点的度数.当中一些度数无限制,求能够生成多少种树 Prufer序列 把一棵树进行下面操作: 1.找到编号最小的叶节点.删除这个节点,然后与这个叶节点相连的点计入序列 ...
- BZOJ 1005 [HNOI2008] 明明的烦恼(组合数学 Purfer Sequence)
题目大意 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为 1 到 N 的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 N( ...
- 【BZOJ】【1005】【HNOI2008】明明的烦恼
Prufer序列/排列组合+高精度 窝不会告诉你我是先做了BZOJ1211然后才来做这题的>_>(为什么?因为我以前不会高精度呀……) 在A了BZOJ 1211和1089之后,蒟蒻终于有信 ...
- BZOJ 1005: [HNOI2008]明明的烦恼 Purfer序列 大数
1005: [HNOI2008]明明的烦恼 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&&生成树计数
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2248 Solved: 898[Submit][Statu ...
随机推荐
- 大数据技术Hadoop笔试题
Hadoop有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上.以下是由应届毕业生网小编J.L为您整理推荐的面试笔试题目和经验,欢迎参考阅读. 单项选择题 1. 下面哪个程序负责 H ...
- linux 下 nc 命令的使用
netcat被誉为网络安全界的'瑞士军刀',一个简单而有用的工具,透过使用TCP或UDP协议的网络连接去读写数据.它被设计成一个稳定的后门工具,能够直接由其它程序和脚本轻松驱动.同时,它也是一个功能强 ...
- video与audio的使用
HTML5 DOM 为 <audio> 和 <video> 元素提供了方法.属性和事件. 这些方法.属性和事件允许您使用 JavaScript 来操作 <audio> ...
- 安装CentOS7,连接mysql提示密码错误
1.grep 'temporary password' /var/log/mysqld.log 如果上面命令没有查看到密码 2.修改my.cnf文件.在mysqld下加入skip-grant-tabl ...
- C# 使用 GDI+ 给图片添加文字,并使文字自适应矩形区域
需求 需求是要做一个编辑文字的页面.用户在网页端写文字,文字区域是个矩形框,用户可以通过下方的拖动条调节文字大小. 如下图: 提交数据的时候前端传文字区域的左上角和右下角定位给后台.因为前端的字体大小 ...
- hadoop2.7.3+spark2.1.0+scala2.12.1环境搭建(3)http://www.cnblogs.com/liugh/p/6624491.html
一.文件准备 scala-2.12.1.tgz 下载地址: http://www.scala-lang.org/download/2.12.1.html 二.工具准备 2.1 Xshell 2.2 X ...
- SQL Server 2012 管理新特性:AlwaysOn 可用性组
SQL Server 2012 新特性(一)管理新特性:AlwaysOn 一.准备环境 1.准备4台计算机 域控制器DC1,IP地址192.168.1.1 主节点SQL1:IP地址192.168.1. ...
- pandas.read_csv参数详解
读取CSV(逗号分割)文件到DataFrame 也支持文件的部分导入和选择迭代 更多帮助参见:http://pandas.pydata.org/pandas-docs/stable/io.html 参 ...
- POJ-2570 Fiber Network---Floyd+二进制表示集合
题目链接: https://vjudge.net/problem/POJ-2570 题目大意: 一些公司决定搭建一个更快的网络,称为"光纤网".他们已经在全世界建立了许多站点,这 ...
- hdu1222&hdu1014 循环群的生成元
hdu1222 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1222 题目大意: 大灰狼追小白兔.小白兔可以躲起来的洞绕成一个圈,大灰狼从0这个点出 ...