zoukankan      html  css  js  c++  java
  • 【prufer编码+组合数学】BZOJ1005 [HNOI2008]明明的烦恼

    Description

      自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?

    Solution

      这道题就是树的计数加强版,多了不要求的情况。

      对于已限制的情况,就是C(n-2,t)*可重复元素的公式,考虑其他不限制的元素,再*(n-t)^(n-2-sum),t为已限制点个数,sum为已限制度数。

      大概就是这个意思,计算要用分解质因数+高精度,具体细节自己推一推。

    Code

      因为是高精乘低精,高精度很好打。

      1A十分感动,感觉最近打代码没以前那么无脑了。

      

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=5e3+5;
     6 
     7 int dy[maxn],pri[maxn],tot[maxn],cnt;
     8 int a[maxn],d[maxn],n,t,len;
     9 
    10 int getpri(){
    11     for(int i=2;i<=n;i++){
    12         if(!dy[i]) pri[++cnt]=i,dy[i]=cnt;
    13         for(int j=1;j<=cnt&&pri[j]*i<=n;j++){
    14             dy[pri[j]*i]=j;
    15             if(i%pri[j]==0) break;
    16         }
    17     }
    18 }
    19 
    20 int add(int x,int k){
    21     while(x!=1){
    22         tot[dy[x]]+=k;
    23         x/=pri[dy[x]];
    24     }
    25 }
    26 
    27 int mul(int x){
    28     for(int i=1;i<=len;i++) a[i]*=x;
    29     for(int i=1;i<=len;i++) if(a[i]>=10){
    30         if(i==len) len++;
    31         a[i+1]+=a[i]/10;
    32         a[i]%=10;
    33     }
    34 }
    35 
    36 int main(){
    37     int sum=0;
    38     scanf("%d",&n);
    39     for(int i=1;i<=n;i++){
    40         scanf("%d",&d[i]);
    41         if(d[i]!=-1) sum+=d[i]-1;
    42     }
    43     if(sum>n-2){
    44         printf("0
    ");
    45         return 0;
    46     }
    47     if(n==1){
    48         printf("1
    ");
    49         return 0;
    50     }
    51     
    52     for(int i=1;i<=n;i++){
    53         if(!d[i]){
    54             printf("0
    ");
    55             return 0;
    56         }
    57         if(d[i]!=-1) t++;
    58     }
    59     
    60     getpri();
    61     for(int i=1;i<=n-2;i++) add(i,1);
    62     for(int i=1;i<=n-2-sum;i++) add(n-t,1);
    63     for(int i=1;i<=n-2-sum;i++) add(i,-1);
    64     for(int i=1;i<=n;i++)
    65         for(int j=1;j<d[i];j++) add(j,-1);
    66         
    67     len=a[1]=1;
    68     for(int i=1;i<=cnt;i++)
    69         for(int j=1;j<=tot[i];j++) mul(pri[i]);
    70         
    71     for(int i=len;i>=1;i--)
    72         printf("%d",a[i]);
    73     return 0;
    74 }
  • 相关阅读:
    Spring-data-jpa和mybatis的比较及两者的优缺点?
    http和https的区别
    Springboot中spring-data-jpa实现拦截器
    RabbitMQ客户端页面认识
    设计模式之策略模式
    设计模式之策略模式应用实例(Spring Boot 如何干掉 if else)
    设计模式之装饰器模式
    网页跳转小程序
    好帖子
    git 回滚操作
  • 原文地址:https://www.cnblogs.com/xkui/p/4593714.html
Copyright © 2011-2022 走看看