【BZOJ】【1005】【HNOI2008】明明的烦恼

Prufer序列/排列组合+高精度


  窝不会告诉你我是先做了BZOJ1211然后才来做这题的>_>(为什么?因为我以前不会高精度呀……)

  在A了BZOJ 1211和1089之后,蒟蒻终于有信心来写这道神题啦= =

  

  嗯还是先说下做法吧~

  ……

  还是出门左转去看黄学长的博客吧……我懒得写了……其实就是Prufer序列+高精度= =嗯就是之前说的那两道题的加和……

  http://hzwer.com/3272.html

  1 /**************************************************************
  2     Problem: 1005
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:188 ms
  7     Memory:1304 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 1005
 11 #include<cstdio>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define rep(i,n) for(int i=0;i<n;++i)
 17 #define F(i,j,n) for(int i=j;i<=n;++i)
 18 #define D(i,j,n) for(int i=j;i>=n;--i)
 19 #define pb push_back
 20 using namespace std;
 21 typedef long long LL;
 22 inline int getint(){
 23     int r=1,v=0; char ch=getchar();
 24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 26     return r*v;
 27 }
 28 const int N=1010;
 29 /*******************template********************/
 30  
 31  
 32 struct bint{
 33     int l,v[5010];
 34     bint(){l=1; memset(v,0,sizeof v);}
 35     int& operator [] (int x){return v[x];}
 36 }ans;
 37 const int Limit=1000;
 38  
 39 void print(bint a){
 40     printf("%d",a[a.l]);
 41     D(i,a.l-1,1) printf("%03d",a[i]);
 42     puts("");
 43 }
 44 bint operator * (bint a,int p){
 45     int tmp=0;
 46     F(i,1,a.l){
 47         a[i]=a[i]*p+tmp;
 48         tmp=a[i]/Limit;
 49         a[i]%=Limit;
 50     }
 51     if (tmp) a[++a.l]=tmp;
 52     return a;
 53 }
 54 int n,a[N],b[N],prime[N],tot,m,cnt;
 55 bool vis[N];
 56 void ready(int n){
 57     F(i,2,n){
 58         if (!vis[i]) prime[++tot]=i;
 59         F(j,1,tot){
 60             if (i*prime[j]>n) break;
 61             vis[i*prime[j]]=1;
 62             if (i%prime[j]==0) break;
 63         }
 64     }
 65 }
 66 void add(int k,int v){
 67     F(j,1,tot){
 68         int x=k;
 69         while (x){
 70             b[j]+=x/prime[j]*v;
 71             x/=prime[j];
 72         }
 73     }
 74 }
 75 int main(){
 76 #ifndef ONLINE_JUDGE
 77     freopen("1005.in","r",stdin);
 78     freopen("1005.out","w",stdout);
 79 #endif
 80     ready(1000);
 81     n=getint();
 82     if (n==1){
 83         a[1]=getint();
 84         if (a[1]<=0) puts("1");
 85         else puts("0");
 86         return 0;
 87     }
 88     F(i,1,n){
 89         a[i]=getint();
 90         if (a[i]==0 || a[i]>n-1) {puts("0"); return 0;}
 91     }
 92     F(i,1,n){
 93         if (a[i]>0){
 94             a[i]-=1;
 95             m+=a[i];
 96         }
 97         else cnt++;
 98     }
 99     if (m>n-2){ puts("0"); return 0;}
100     int tmp=n-2;
101     F(i,1,n){
102         if (a[i]>0){
103             add(tmp,1);
104             add(a[i],-1);
105             add(tmp-a[i],-1);
106             tmp-=a[i];
107         }
108     }
109 //  F(i,1,tot) printf("%d ",b[i]); puts("");
110     ans[1]=1;
111     F(i,1,tot) F(j,1,b[i]) ans=ans*prime[i];
112     F(j,1,tmp) ans=ans*cnt;
113     print(ans);
114     return 0;
115 }
View Code

1005: [HNOI2008]明明的烦恼

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2964  Solved: 1182
[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

Source

[Submit][Status][Discuss]

 

posted @ 2015-05-15 21:38  Tunix  阅读(167)  评论(0编辑  收藏  举报