zoukankan      html  css  js  c++  java
  • BZOJ1005: [HNOI2008]明明的烦恼

    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编码的性质:
      (1)树的prufer编码的实现
            不断 删除树中度数为1的最小序号的点,并输出与其相连的节点的序号  直至树中只有两个节点
      (2)通过观察我们可以发现
            任意一棵n节点的树都可唯一的用长度为n-2的prufer编码表示
            度数为m的节点的序号在prufer编码中出现的次数为m-1
      (3)怎样将prufer编码还原为一棵树??
            从prufer编码的最前端开始扫描节点,设该节点序号为 u ,寻找不在prufer编码的最小序号且没有被标记的节点 v ,连接   u,v,并标记v,将u从prufer编码中删除。扫描下一节点。
     
     
     
     
    该题需要将树转化为prufer编码:
     n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数。
    则            
    所以要求在n-2大小的数组中插入tot各序号,共有种插法;
    在tot各序号排列中,插第一个节点的方法有种插法;
                               插第二个节点的方法有种插法;
                                          ………
    另外还有m各节点无度数限制,所以它们可任意排列在剩余的n-2-tot的空间中,排列方法总数为
     
    根据乘法原理:
     
     
    然后就要高精度了…..但高精度除法太麻烦了,显而易见的排列组合一定是整数,所以可以进行质因数分解,再做一下相加减。
     
     
    关于n!质因数分解有两种方法,第一种暴力分解,这里着重讲第二种。
      若p为质数,则n!可分解为 一个数*,其中  <n
     
    所以 

    ——转自怡红公子

    链接:http://www.cnblogs.com/noip/archive/2013/03/10/2952520.html
     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 struct bignum {
     5     int l, a[10000];
     6      
     7     bignum (int t) {
     8         l = 0; memset(a, 0, sizeof(0));
     9         while (t != 0) {
    10             a[++l] = t % 10000;
    11             t /= 10000;
    12         }
    13         if (l == 0) l = 1;
    14     }
    15      
    16     void mul(int k) {
    17         for (int i = 1; i <= l; i++)
    18             a[i] *= k;
    19         for (int i = 1; i <= l; i++)
    20             if (a[i] >= 10000) {
    21                 int t = i;
    22                 do {
    23                     a[t + 1] += a[t] / 10000;
    24                     a[t++] %= 10000;
    25                 } while (a[t] >= 10000);
    26             }
    27         while (a[l + 1] > 0) l++;
    28     }
    29      
    30     void print() {
    31         printf("%d", a[l]);
    32         for (int i = l - 1; i >= 1; i--)
    33             printf("%04d", a[i]);
    34         printf("
    ");
    35     }
    36 };
    37 int n, m = 0, tot = 0, d[1001], prime[1001], cnt[1001];
    38  
    39 bool judge(int k) {
    40     for (int i = 2; i <= sqrt(k); i++)
    41         if (k % i == 0) return false;
    42     return true;
    43 }
    44  
    45 void makelist(int n) {
    46     prime[0] = 0;
    47     for (int i = 2; i <= n; i++)
    48         if (judge(i)) prime[++prime[0]] = i;
    49 }
    50  
    51 void compute(int k, int t) {
    52     for (int i = 1; i <= prime[0] && prime[i] <= k; i++) {
    53         int x = 0, n = k, p = prime[i];
    54         while (n != 0) {
    55             x += n / p;
    56             n /= p;
    57         }
    58         cnt[i] += x * t;
    59     }
    60 }
    61  
    62 int main() {
    63     //freopen("input.txt", "r", stdin);
    64     //freopen("output.txt", "w", stdout);
    65     scanf("%d", &n);
    66     for (int i = 1; i <= n; i++) {
    67         scanf("%d", &d[i]);
    68         if (d[i] == -1) m++;
    69             else tot += d[i] - 1;
    70     }
    71      
    72     makelist(n);
    73     memset(cnt, 0, sizeof(cnt));
    74     compute(n - 2, 1);
    75     compute(n - 2 - tot, -1);
    76     for (int i = 1; i <= n; i++)
    77         if (d[i] != -1) compute(d[i] - 1, -1);
    78  
    79     bignum ans = 1;
    80     for (int i = 1; i <= prime[0]; i++)
    81         for (int j = 1; j <= cnt[i]; j++)
    82             ans.mul(prime[i]);
    83     for (int i = 1; i <= n - 2 - tot; i++)
    84         ans.mul(m);
    85     ans.print();
    86     return 0;
    87 }
    BZOJ1005
  • 相关阅读:
    python3操作mysql数据库表01(封装查询单条、多条数据)
    python3操作mysql数据库表01(基本操作)
    Python3基础02(列表和字符串处理)
    Python3+Selenium3+webdriver学习笔记14(等待判断 鼠标事件 )
    Python3+Selenium3+webdriver学习笔记13(js操作应用:弹出框无效如何处理)
    Python3+Selenium3+webdriver学习笔记12(js操作应用:滚动条 日历 内嵌div)
    Python3+Selenium3+webdriver学习笔记11(cookie处理)
    Python3+Selenium3+webdriver学习笔记10(元素属性、页面源码)
    Python3+Selenium3+webdriver学习笔记9(发送富文本信息及上传文件处理)
    Python3+Selenium3+webdriver学习笔记8(单选、复选框、弹窗处理)
  • 原文地址:https://www.cnblogs.com/VOHAHRV/p/4931059.html
Copyright © 2011-2022 走看看