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

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 6539  Solved: 2558
    [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数列 和 节点度数 这种东西,自行Google。

    Plufer数列有一下性质:

    1、可以表示为任意一个长度为n-2的数列

    2、任意一点的度数为d[i],则该节点在数列中出现d[i]-1次

    3、因此数列的总长度为:

    [sum=sum _{i=1}^{n} (d[i]-1)]

    得出这个总长度的前提是,所有度数已知,但题目并没有给出所有的度数。但是我们可以计算出已知n个点的度数,可以构造出多少种Prufer数列:

    [frac{(n-2)!}{prod _{i-1}^{n}(d[i]-1)!}]

    那么已知cnt个点的度数,可以构造出多少种Prufer数列呢?

    [C_{n-2}^{sum} imes frac{sum!}{prod _{i-1}^{n}(d[i]-1)!}]

    那么已知cnt个点的度数,n-cnt个点的度数未知,可以构造出多少种Prufer数列呢?

    [ans=C_{n-2}^{sum} imesfrac{sum!}{prod _{i-1}^{n}(d[i]-1)!} imes(n-cnt)^{n-2-sum}]

    最终可以化简得:

    [ans=frac{(n-2)!}{(n-2-sum)!prod _{i-1}^{n}(d[i]-1)!} imes(n-cnt)^{n-2-sum}]

    沿用了之前高精度乘除单精度的模板,减少代码量(明明是增加了)

    虽说质因数分解更能显示bigger。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<iomanip>
      6 using namespace std;
      7 
      8 const int MAXN=1000;
      9 const int DLEN=4;
     10 const int WIDE=10000;
     11 class BigNum
     12 {
     13 public:
     14     int NUM[MAXN];
     15     int L;
     16     bool flag;
     17     BigNum(){memset(NUM,0,sizeof(NUM));L=1;flag=0;}
     18     BigNum(const BigNum &T){memcpy(NUM,T.NUM,sizeof(NUM));L=T.L;flag=T.flag;}
     19     BigNum(int n){memset(NUM,0,sizeof(NUM));NUM[0]=n;L=1;while(NUM[L-1]>=WIDE){NUM[L]+=NUM[L-1]/WIDE;NUM[L-1]%=WIDE;L++;}flag=0;}
     20 };
     21 
     22 void Output(const BigNum T)
     23 {
     24     if(T.flag==1) cout<<'-';
     25     cout<<T.NUM[T.L-1];
     26     for(int i=T.L-2;i>=0;i--)
     27     {
     28         cout.width(DLEN);
     29         cout.fill('0');
     30         cout<<T.NUM[i];
     31     }
     32 }
     33 
     34 BigNum Mult(const BigNum A,int B)
     35 {
     36     BigNum C(A);
     37     int i,tmp,k=0;
     38     for(i=0;i<C.L||k;i++)
     39     {
     40         tmp=C.NUM[i]*B+k;
     41         k=tmp/WIDE;
     42         C.NUM[i]=tmp%WIDE;
     43     }
     44     C.L=i;
     45     return C;
     46 }
     47 
     48 BigNum Div(const BigNum A,int B)
     49 {
     50     BigNum C(A);
     51     int k=0;
     52     for(int i=C.L-1;i>=0;i--)
     53     {
     54         k=k*WIDE+C.NUM[i];
     55         C.NUM[i]=k/B;
     56         k%=B;
     57     }
     58     while(C.NUM[C.L-1]==0) C.L--;
     59     return C;
     60 }
     61 
     62 int n,sum,cnt;
     63 int d[1005];
     64 bool flag;
     65 BigNum ans(1);
     66 
     67 int main()
     68 {
     69     scanf("%d",&n);
     70     for(int i=1;i<=n;i++)
     71     {
     72         scanf("%d",&d[i]);
     73         if(d[i]==0||d[i]>n-1) flag=1;
     74         if(d[i]==-1) continue;
     75         sum+=d[i]-1;
     76         cnt++;
     77     }
     78     if(n==1)
     79     {
     80         if(d[1]==0||d[1]==-1) printf("1
    ");
     81         else printf("0
    ");
     82         return 0;
     83     }
     84     if(n==2)
     85     {
     86         if((d[1]==0||d[1]>1)&&(d[2]==0||d[2]>1)) printf("1
    ");
     87         else printf("0
    ");
     88         return 0;
     89     }
     90     if(flag)
     91     {
     92         printf("0
    ");
     93         return 0;
     94     }
     95     for(int i=n-1-sum;i<=n-2;i++)
     96         ans=Mult(ans,i);
     97     for(int i=1;i<=n-2-sum;i++)
     98         ans=Mult(ans,n-cnt);
     99     for(int i=1;i<=cnt;i++)
    100         for(int j=1;j<=d[i]-1;j++)
    101             ans=Div(ans,j);
    102     Output(ans);
    103     return 0;
    104 }
  • 相关阅读:
    网络与系统安全第四次作业
    2018-2019-1 20189203《linux内核原理与分析》第六周作业
    《网络攻防实践》第五周作业
    《网络攻防实践》第四周作业
    《网络攻防实践》第三周作业
    《网络攻防实践》第二周作业
    《网络攻防实践》第一周作业
    《Linux内核原理与分析》第九周作业
    《Linux内核原理与分析》第八周作业
    《Linux内核原理与分析》第七周作业
  • 原文地址:https://www.cnblogs.com/InWILL/p/9291556.html
Copyright © 2011-2022 走看看