[HNOI2008]明明的烦恼

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 5907  Solved: 2305
[Submit][Status][Discuss]

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

 
题解:
    prufer编码对于n个节点的数,是有n-2个数字的,不同的排列对应着不同的
    树,一个度为x的点,出现在prufer编码中的次数是x-1。
    所有就可以组合数学来解决这个问题。
    

假设度数有限制的点的数量为 cnt,他们的度数分别为:d[i]

另:

那么,在 Purfer Sequence 中的不同排列的总数为:

而剩下的 n-2-sum 个位置,可以随意的排列剩余的 n-cnt 个点,于是,总的方案数就应该是:

化简之后为:

算了我在说一下,最后那个就是说,给了n-2-sum个位置,可以随便填数,填什么表示这个位置属于谁,好理解吧。

在有解的情况下,计算该结果输出就行了

无解的情况,就比如说超出了个数,这样子的,判断一下,根据prufer性质。

 #include <bits/stdc++.h>
using namespace std;
int d[];
struct bigint
{
int a[], len; bigint()
{
memset(a, , ), len = ;
} bigint operator* (const int &rhs) const
{
bigint ans;
ans.len = len + ;
for(int i = ; i <= len; ++i)
ans.a[i] += a[i] * rhs;
for(int i = ; i < ans.len; ++i)
if(ans.a[i] > )
{
ans.a[i + ] += ans.a[i] / ;
ans.a[i] %= ;
}
while(!ans.a[--ans.len]);
return ans;
} bigint operator/ (const int &rhs) const
{
bigint ans;
ans = *this, ++ans.len;
for(int i = ans.len; i; --i)
{
ans.a[i - ] += ans.a[i] % rhs * ;
ans.a[i] /= rhs;
}
while(!ans.a[--ans.len]);
return ans;
}
}; int main()
{
int n, sum = , cnt = ;
bigint ans;
scanf("%d", &n);
for(int i = ; i <= n; ++i)
{
scanf("%d", d + i);
if(!d[i])
{
puts("");
return ;
}
if(~d[i]) ++cnt, sum += d[i] - ;
}
if(sum > * n - )
{
puts("");
return ;
}
ans.a[] = ;
for(int i = n - - sum; i < n - ; ++i)
ans = ans * i;
for(int i = ; i <= n - - sum; ++i)
ans = ans * (n - cnt);
for(int i = ; i <= n; ++i)
for(int j = ; j <= d[i] - ; ++j)
ans = ans / j;
for(int i = ans.len; i; --i)
printf("%d", ans.a[i]);
puts("");
}

bzoj 1005 [HNOI2008] 明明的烦恼 (prufer编码)的更多相关文章

  1. BZOJ 1005 [HNOI2008]明明的烦恼 (Prufer编码 + 组合数学 + 高精度)

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

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

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

  3. BZOJ.1005.[HNOI2008]明明的烦恼(Prufer 高精 排列组合)

    题目链接 若点数确定那么ans = (n-2)!/[(d1-1)!(d2-1)!...(dn-1)!] 现在把那些不确定的点一起考虑(假设有m个),它们在Prufer序列中总出现数就是left=n-2 ...

  4. BZOJ 1005 [HNOI2008]明明的烦恼 ★(Prufer数列)

    题意 N个点,有些点有度数限制,问这些点可以构成几棵不同的树. 思路 [Prufer数列] Prufer数列是无根树的一种数列.在组合数学中,Prufer数列是由一个对于顶点标过号的树转化来的数列,点 ...

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

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

  6. BZOJ 1005: [HNOI2008]明明的烦恼( 组合数学 + 高精度 )

    首先要知道一种prufer数列的东西...一个prufer数列和一颗树对应..然后树上一个点的度数-1是这个点在prufer数列中出现次数..这样就转成一个排列组合的问题了.算个可重集的排列数和组合数 ...

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

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

  8. BZOJ 1005 [HNOI2008]明明的烦恼 purfer序列,排列组合

    1005: [HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少 ...

  9. BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1005 题意: Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标 ...

随机推荐

  1. d3学习笔记

    (1)使用enter()函数. 当要创建新的绑定数据的元素,必须使用enter().这个方法会分析当前选择的DOM元素和传给它的数据,如果数据值比对应的DOM元素多,就创建一个新的占位元素.然后把这个 ...

  2. jQuery委托

    $('#container').on('click', '.elementClass', function() { // code }); http://stackoverflow.com/quest ...

  3. $.ajax json 在本地正常 上传服务器不正常

    $.ajax( {                        url:"url",// 跳转到 action                        data:{name ...

  4. Windows远程桌面连接复制文件失败或非常慢

    环境搭建过程中经常会遇到需要将文件从本机传到云服务器或者企业内部服务器上的场景,此时如果文件过大的话要传个半天或者直接告诉你复制失败,让人好生无奈 ~ ~.   windows环境下,可以将本地磁盘映 ...

  5. css3 transform + deviceorientation实现图片旋转效果

    1. 陀螺仪deviceorientation的使用,参考<关于陀螺仪deviceorientation>https://segmentfault.com/a/11900000071838 ...

  6. windows保存tomcat的控制台日志到文件

    startup.bat修改:call "%EXECUTABLE%" start %CMD_LINE_ARGS%改为:call "%EXECUTABLE%" ru ...

  7. Matlab plotyy画双纵坐标图实例

    Matlab plotyy画双纵坐标图实例 x = 0:0.01:20;y1 = 200*exp(-0.05*x).*sin(x);y2 = 0.8*exp(-0.5*x).*sin(10*x);[A ...

  8. 删数问题(Noip1994)

    1321:[例6.3]删数问题(Noip1994) 时间限制: 1000 ms         内存限制: 65536 KB提交数: 5127     通过数: 1595 [题目描述] 输入一个高精度 ...

  9. java_String类练习

    public class StringTest { //1.模拟trim方法,去除字符串两端的空格 public static void main(String[] args) { String st ...

  10. Java中List集合的遍历

    一.对List的遍历有三种方式 List<String> list = new ArrayList<String>(); list.add("testone" ...