zoukankan      html  css  js  c++  java
  • 【BZOJ 1005】 1005: [HNOI2008]明明的烦恼 (prufer数列+高精度)

    1005: [HNOI2008]明明的烦恼

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 4981  Solved: 1941

    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

    Source

    【分析】

      先特判无解的情况。

      假设$sum=sum(d[i]-1)|[d[i]!=-1]$

      $ss=sum 1 [d[i]!=-1]$

      则$Ans=C_{n-2}^{sum}*dfrac{sum!}{Pi(d[i]-1)!}*(n-ss)^{n-2-sum}$

      即$Ans=dfrac{(n-2)!}{(n-2-sum)!*Pi(d[i]-1)!}*(n-ss)^{n-2-sum}$

      这些数值都不会超过n的,先手动消因子,然后Ans用高精度,就是高精乘单精。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 1010
     8 #define mod 10000
     9 
    10 int cnt[Maxn],d[Maxn];
    11 
    12 struct hugeint
    13 {
    14     int w[Maxn],l;
    15     hugeint() {memset(w,0,sizeof(w));l=0;}
    16     friend hugeint operator * (hugeint x,int y)
    17     {
    18         for(int i=0;i<=x.l;i++) x.w[i]*=y;
    19         for(int i=0;i<=x.l;i++) x.w[i+1]+=x.w[i]/mod,x.w[i]%=mod;
    20         while(x.w[x.l+1]!=0) x.w[x.l+2]+=x.w[x.l+1]/mod,x.w[++x.l]%=mod;
    21         while(x.w[x.l]==0&&x.l>0) x.l--;
    22         return x;
    23     }
    24 };
    25 
    26 void cal(int x,int y)
    27 {
    28     for(int i=2;i<=x*x;i++) if(x%i==0)
    29     {
    30         while(x%i==0) cnt[i]+=y,x/=i;
    31     }
    32     if(x!=1) cnt[x]+=y;
    33 }
    34 
    35 int main()
    36 {
    37     int n;
    38     scanf("%d",&n);
    39     for(int i=1;i<=n;i++) scanf("%d",&d[i]);
    40     if(n==1&&d[1]>0) printf("0
    ");
    41     else
    42     {
    43         int sum=0,ss=0;
    44         for(int i=1;i<=n;i++) if(d[i]!=-1) sum+=d[i]-1,ss++;
    45         else if(d[i]==0||d[i]>=n) {printf("0
    ");return 0;}
    46         if(sum>n-2) printf("0
    ");
    47         else
    48         {
    49             // for(int i=1;i<=n;i++) if(d[i]!=-1) d[i]--;
    50             for(int i=1;i<=n;i++) cnt[i]=0;
    51             for(int i=2;i<=n-2;i++) cal(i,1);
    52             for(int i=2;i<=n-2-sum;i++) cal(i,-1);
    53             for(int i=1;i<=n;i++) if(d[i]!=-1)
    54             {
    55                 for(int j=2;j<=d[i]-1;j++) cal(j,-1);
    56             }
    57             cal(n-ss,n-2-sum);
    58             hugeint ans;ans.w[0]=1;
    59             for(int i=2;i<=n;i++) while(cnt[i]--) ans=ans*i;
    60             printf("%d",ans.w[ans.l]);
    61             for(int i=ans.l-1;i>=0;i--) printf("%04d",ans.w[i]);printf("
    ");
    62         }
    63     }
    64     return 0;
    65 }
    View Code

    2017-04-25 15:36:48

  • 相关阅读:
    【重点推荐】五美凡生论
    语言哲学宣言2018
    四要同环图
    知识分子必须毫不留情反对一切“教养阶层”
    世界上任何一件事的五个模块
    Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?
    Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?
    有没有简单易用的数据挖掘工具?
    BI、OLAP、多维分析、CUBE 这几个词是什么关系?
    传说中的中国复杂报表都长什么样?有什么特点?
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6762407.html
Copyright © 2011-2022 走看看