zoukankan      html  css  js  c++  java
  • 【prufer编码】BZOJ1211 [HNOI2004]树的计数

    Description

      给定一棵树每个节点度的限制为di,求有多少符合限制不同的树。

    Solution

      发现prufer码和度数必然的联系

      prufer码一个点出现次数为它的度数-1

      我们依然可以把树转成序列进行处理

      只是每个元素出现次数受到了限制

      于是就是有重复元素的排列问题了

      公式很好推

    Code

      特殊情况判一判

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define ll long long
     5 using namespace std;
     6 const int maxn=155;
     7 
     8 int dy[maxn],pri[maxn];
     9 int tot[maxn],cnt;
    10 int d[maxn],n,sum;
    11 
    12 int getpri(){
    13     for(int i=2;i<=n;i++){
    14         if(!dy[i]) pri[++cnt]=i,dy[i]=cnt;
    15         for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
    16             dy[pri[j]*i]=j;
    17             if(i%pri[j]==0) break;
    18         }
    19     }
    20 }
    21 
    22 int add(int x,int k){
    23     while(x!=1){
    24         tot[dy[x]]+=k;
    25         x/=pri[dy[x]];
    26     }
    27 }
    28 
    29 ll pow(ll x,ll k){
    30     ll ret=1;
    31     for(int i=k;i;i>>=1,x=x*x)
    32         if(i&1) ret=ret*x;
    33     return ret;
    34 }
    35 
    36 int main(){
    37     scanf("%d",&n);
    38     for(int i=1;i<=n;i++)
    39         scanf("%d",&d[i]),sum+=d[i];
    40     if(sum!=2*n-2){
    41         printf("0
    ");
    42         return 0;
    43     }
    44     if(n==1){
    45         printf("1
    ");
    46         return 0;
    47     }
    48     
    49     getpri();
    50     
    51     for(int i=1;i<=n-2;i++) add(i,1);
    52     for(int i=1;i<=n;i++)
    53         if(!d[i]){
    54             printf("0
    ");
    55             return 0;
    56         }
    57         else for(int j=1;j<d[i];j++) add(j,-1);
    58     
    59     ll ans=1;
    60     for(int i=1;i<=cnt;i++)
    61         ans=ans*pow(1ll*pri[i],tot[i]);
    62     printf("%lld
    ",ans);
    63     return 0;
    64 }
  • 相关阅读:
    多态
    多继承
    传宗接代——继承
    解决vue项目更新版本后浏览器的缓存问题
    escape()、encodeURI()、encodeURIComponent()三种编码方式的区别
    epoll使用总结
    探讨c/c++的指针
    基于linux的pthread_t封装一个Thread类
    unix高并发编程中遇到的问题和笔记
    面向对象分析与设计 实验七
  • 原文地址:https://www.cnblogs.com/xkui/p/4593705.html
Copyright © 2011-2022 走看看