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)的更多相关文章

  1. [HNOI2008][bzoj 1005]明明的烦恼(prufer序列)

    1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7121  Solved: 2816[Submit][Stat ...

  2. BZOJ 1005 明明的烦恼

    Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 ...

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

    题解:n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数. 则               所以要求在n-2大小的数组中插入tot各序号,共有种插法: 在tot各序号排列中,插第一个节点的 ...

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

    有一种东西叫树的prufer序列,一个树的与一个prufer序列是一一对应的关系. 设有m个度数确定的点,这些点的度为dee[i],那么每个点在prufer序列中出现了dee[i]-1次. 由排列组合 ...

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

    题目大意:给定一棵n个节点的树的节点的度数.当中一些度数无限制,求能够生成多少种树 Prufer序列 把一棵树进行下面操作: 1.找到编号最小的叶节点.删除这个节点,然后与这个叶节点相连的点计入序列 ...

  6. BZOJ 1005 [HNOI2008] 明明的烦恼(组合数学 Purfer Sequence)

    题目大意 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为 1 到 N 的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 N( ...

  7. 【BZOJ】【1005】【HNOI2008】明明的烦恼

    Prufer序列/排列组合+高精度 窝不会告诉你我是先做了BZOJ1211然后才来做这题的>_>(为什么?因为我以前不会高精度呀……) 在A了BZOJ 1211和1089之后,蒟蒻终于有信 ...

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

    1005: [HNOI2008]明明的烦恼 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

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

    1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2248  Solved: 898[Submit][Statu ...

随机推荐

  1. 201421123042 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 答: 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户 ...

  2. style scoped

    scoped: 只在父div和其内容内生效,

  3. installutil 安装windows service

    1:路径:C:\Windows\Microsoft.NET\Framework\v4.0.30319 2:执行指令:C:\Windows\Microsoft.NET\Framework\v4.0.30 ...

  4. JAVA_SE基础——49.多态的应用

    因为多态对以后开发的重要性,因此我在这里专门开个多态的应用来加深讲解,希望想弄懂多态的同学能耐心看完. 了解了对象多态性后,那么这多态到底有哪些用处了? 下面要求设计一个方法,要求此方法可以接受A类的 ...

  5. Extensions in UWP Community Toolkit - FrameworkElement Extensions

    概述 UWP Community Toolkit Extensions 中有一个为FrameworkElement 提供的扩展 - FrameworkElement Extensions,本篇我们结合 ...

  6. 【原创】公司各个阶段 CTO 需要做什么?(上篇)

    CTO 是企业内技术最高负责人,对企业的发展起到至关重要的作用.但随着公司的不断发展,CTO 的工作重心也会不断变化.只有在正确的阶段做正确的事,才能更好地为公司做出贡献.我是空中金融 CTO ,TG ...

  7. Netty事件监听和处理(上)

    陪产假结束了,今天又开始正常上班了,正好赶上米粉节活动,又要忙上一阵了,米粉节活动时间为4.03 - 4.10,有不少优惠,感兴趣的可以关注mi.com或小米商城app. 今天给大家送了福利:小爱音箱 ...

  8. emqtt 试用(七)追踪

    追踪 EMQ 消息服务器支持追踪来自某个客户端(Client)的全部报文,或者发布到某个主题(Topic)的全部消息. 追踪客户端(Client): ./bin/emqttd_ctl trace cl ...

  9. Docker学习笔记 - Docker容器的日志

    docker logs  [-f]  [-t]  [--tail]  容器名 -f -t --tail="all" 无参数:返回所有日志 -f 一直跟踪变化并返回 -t 带时间戳返 ...

  10. 新概念英语(1-119)who call out to the thieves in the dark?

    who call out to the thieves in the dark? A true story Do you like stories? I want to tell you a true ...