zoukankan      html  css  js  c++  java
  • BZOJ 1005 明明的烦恼

    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

    利用Purfer Sequence,参见:http://www.cnblogs.com/zhj5chengfeng/archive/2013/08/23/3278557.html

     1 #include<cstring>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 using namespace std;
     5 
     6 #define maxn 1010
     7 int d[maxn],n,sum,cnt,tot,prime[maxn],num[maxn];
     8 bool exist[maxn];
     9 struct node
    10 {
    11     int a[maxn*10],len;
    12     node(){memset(a,0,sizeof(a)); len = 1;}
    13     friend inline node operator *(node &x,int y)
    14     {
    15         node z; z.len = x.len + 3;
    16         int i;
    17         for (i = 1;i <= z.len;++i)
    18         {
    19             z.a[i] += x.a[i] * y;
    20             z.a[i+1] += z.a[i] / 10;
    21             z.a[i] %= 10;
    22         }
    23         while (!z.a[z.len]) --z.len;
    24         return z;
    25     }
    26 
    27     inline void print() {for (int i = len;i;--i) printf("%d",a[i]);}
    28 }ans;
    29 
    30 inline void ready()
    31 {
    32     int i,j;
    33     for (i = 2;i <= 1000;++i)
    34         if (!exist[i])
    35         {
    36             exist[i] = true;
    37             prime[++tot] = i;
    38             for (j = i*i;j <= 1000;j += i)
    39                 exist[j] = true;
    40         }
    41 }
    42 
    43 inline bool okay()
    44 {
    45     for (int i = 1;i <= n;++i)
    46     {
    47         if (d[i] > 0) sum += d[i] - 1,++cnt;
    48         if (d[i] == 0) return false;
    49     }
    50     if (sum + n - cnt > 2*(n-1)) return false;
    51     if (cnt == n && sum != 2*(n-1)) return false;
    52     return true;
    53 }
    54 
    55 inline void Div(int a,int bei)
    56 {
    57     if (a == 0) return;
    58     if (bei == 0) return;
    59     for (int i = 1;i <= tot;++i)
    60     {
    61         if (a == 1) break;
    62         if (a % prime[i] == 0)
    63         {
    64             int t = 0;
    65             while (a % prime[i] == 0) ++t,a /= prime[i];
    66             num[i] += t * bei;
    67         }
    68     }
    69 }
    70 
    71 inline void calc()
    72 {
    73     ready();
    74     for (int i = 1;i <= n-2;++i) Div(i,1);
    75     Div(n - cnt,n-sum-2);
    76     for (int i = 1;i <= n-2-sum;++i) Div(i,-1);
    77     for (int i = 1;i <= n;++i) if (d[i] != -1)
    78         for (int j = 1;j < d[i];++j) Div(j,-1);
    79     ans.a[1] = 1;
    80     for (int i = 1;i <= tot;++i)
    81         for (int j = 1;j <= num[i];++j)
    82             ans = ans * prime[i];
    83     ans.print();
    84 }
    85 
    86 int main()
    87 {
    88     scanf("%d",&n); int i;
    89     for (i = 1;i <= n;++i) scanf("%d",d+i);
    90     if (!okay()) printf("%d",0);
    91     else calc();
    92     return 0;
    93 }
    View Code
    高考结束,重新回归。
  • 相关阅读:
    饮冰三年-人工智能-linux-03 Linux文件管理(权限管理+归档+压缩)
    饮冰三年-人工智能-linux-02 初始Linux
    饮冰三年-人工智能-linux-01通过VM虚拟机安装contes系统
    测试joinablequeue
    生产者消费者模型
    队列
    优化抢票
    昨日回顾
    抢票小程序
    守护进程
  • 原文地址:https://www.cnblogs.com/mmlz/p/4213057.html
Copyright © 2011-2022 走看看