zoukankan      html  css  js  c++  java
  • bzoj1005: [HNOI2008]明明的烦恼(prufer+高精度)

    1005: [HNOI2008]明明的烦恼

    题目:传送门 

    题解:

       毒瘤题啊天~

       其实思考的过程还是比较简单的。。。

       首先当然还是要了解好prufer序列的基本性质啦

       那么和1211大体一致,主要还是利用组合数学:

       首先我们把度数和-n记录为sum,那么根据prufer序列,序列的元素个数就是n-2

       那就是要在n-2个位置中选sum个,然后就是分别根据度数要求算每个元素在sum个位置中的方案,然后乘起来。最后还要乘上没有度数要求的元素的方案数就...ok啦

       思考两分钟...代码两小时...太菜啦!!!!

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define qread(x) x=read()
     7 using namespace std;
     8 inline int read()
     9 {
    10     int f=1,x=0;char ch;
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return f*x;
    14 }
    15 struct node
    16 {
    17     int len,a[11000];
    18     node(){memset(a,0,sizeof(a));}
    19 }no,n1;
    20 void chengfa(int x)
    21 {
    22     int i;
    23     for(i=1;i<=no.len;i++)no.a[i]=no.a[i]*x;
    24     for(i=1;i<=no.len;i++)
    25     {
    26         no.a[i+1]+=no.a[i]/10;
    27         no.a[i]%=10;
    28     }
    29     i=no.len;
    30     while(no.a[i+1]>0)
    31     {
    32         i++;
    33         no.a[i+1]+=no.a[i]/10;
    34         no.a[i]%=10;
    35     }
    36     no.len=i;
    37     while(no.a[no.len]==0 && no.len>1)no.len--;
    38 }
    39 bool pd(int x)
    40 {
    41     if(x<2)return false;
    42     double t=sqrt(double(x+1));
    43     for(int i=2;i<=t;i++)
    44         if(x%i==0)
    45             return false;
    46     return true;
    47 }
    48 int n,d[1100],pr[1100],s[1100];
    49 int main()
    50 {
    51     scanf("%d",&n);int cnt=0,sum=0;
    52     if(n==1){qread(d[1]);if(d[1]){printf("0
    ");return 0;}else {printf("1
    ");return 0;}}
    53     for(int i=1;i<=n;i++)
    54     {
    55         qread(d[i]);
    56         if(d[i]==0){printf("0
    ");}
    57         if(d[i]==-1)cnt++;
    58         else d[i]-=1,sum+=d[i];
    59     }
    60     if(sum>n-2){printf("0
    ");return 0;}
    61     if(sum<n-2 && cnt==0){printf("0
    ");return 0;}
    62     int len=0;
    63     for(int i=2;i<=n;i++)if(pd(i))pr[++len]=i;
    64     for(int i=2;i<=n-2;i++)
    65     {
    66         int x=i;
    67         for(int j=1;j<=len;j++)
    68             while(x%pr[j]==0 && x!=0)
    69                 s[j]++,x/=pr[j];
    70     }
    71     for(int i=2;i<=n-2-sum;i++)
    72     {
    73         int x=i;
    74         for(int j=1;j<=len;j++)
    75             while(x%pr[j]==0 && x!=0)
    76                 s[j]--,x/=pr[j];
    77     }
    78     for(int i=1;i<=n;i++)
    79         if(d[i]>0)
    80         {
    81             for(int k=2;k<=d[i];k++)
    82             {
    83                 int x=k;
    84                 for(int j=1;j<=len;j++)
    85                     while(x%pr[j]==0 && x!=0)
    86                         s[j]--,x/=pr[j];
    87             }
    88         }
    89     no.a[1]=1;no.len=1;
    90     for(int i=1;i<=len;i++)
    91         while(s[i]--)
    92             chengfa(pr[i]);
    93     for(int i=1;i<=n-2-sum;i++)chengfa(cnt);
    94     for(int i=no.len;i>=1;i--)
    95         printf("%d",no.a[i]);
    96     printf("
    ");
    97     return 0;
    98 }

       

  • 相关阅读:
    [面试题]去除字符串中相邻两个字符的重复
    [面试题]单向链表的倒序索引值?
    Android数据存储——文件读写操作(File)
    python操作Excel读写(使用xlrd和xlrt)
    在Ubuntu上安装qq2012客户端
    sharepoint 2010开发webpart(转)

    【Sharepoint 2007】WebPart开发、部署过程全记录(转)
    sharepoint2010最初的了解
    基于windows验证的moss2010站点登录域后还弹出对话框解决方法(转)
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8336149.html
Copyright © 2011-2022 走看看