BZOJ 1005([HNOI2008]明明的烦恼-Prufer数列-树与数组的一一对应)
2013-05-09 14:17
316 查看
1005: [HNOI2008]明明的烦恼
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1263 Solved: 498
[Submit][Status][Discuss]
Description
自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?Input
第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1Output
一个整数,表示不同的满足要求的树的个数,无解输出0Sample Input
31
-1
-1
Sample Output
2HINT
两棵树分别为1-2-3;1-3-2PS:总之就是每一个树都与一个prufer编码一一对应,然后prufer编码里的数出现的个数正好是树的这个点的度数减1。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define ForD(i,n) for(int i=n;i>=1;i--) #define MAXN (1000+10) #define MAXLen (100000+10) #define F (10000) int n,degree[MAXN],T=0,blank_pos; struct mul_arr { int a[MAXN]; int& operator[](int i){return a[i];} mul_arr(){memset(a,0,sizeof(a));} mul_arr(int m,int k) //pow(m,k) { memset(a,0,sizeof(a)); for(int i=2;i*i<=m;i++) while (!(m%i)) { a[i]+=k;m/=i; } if (m>1) a[m]+=k; } friend mul_arr operator-(mul_arr a,mul_arr b){For(i,n) a[i]-=b[i]; return a;} friend mul_arr operator+(mul_arr a,mul_arr b){For(i,n) a[i]+=b[i]; return a;} void print(){For(i,n) cout<<a[i]<<' ';cout<<endl;} }_ans,jc; struct Highn { int a[MAXN],size; int& operator[](int i){return a[i];} Highn():size(0){memset(a,0,sizeof(a));} Highn(int x) { size=0;memset(a,0,sizeof(a)); while (x) { a[++size]+=x%F; x/=F; } } friend Highn operator*(Highn a,Highn b) { Highn c; For(i,a.size) For(j,a.size) { c[i+j-1]+=a[i]*b[j]; c[i+j]+=c[i+j-1]/F; c[i+j-1]%=F; } c.size=a.size+b.size; while (c.size&&!c[c.size]) c.size--; return c; } friend Highn operator*(Highn a,int b) { For(i,a.size) a[i]*=b; For(i,a.size) a[i+1]+=a[i]/F,a[i]%=F; a.size++;while (a.size&&!a[a.size]) a.size--; return a; } void print() { printf("%d",a[size]); ForD(i,size-1) { printf("%04d",a[i]); }puts(""); } }ans; int v[MAXN]={0}; int main() { freopen("bzoj1005.in","r",stdin); scanf("%d",&n);blank_pos=n-2; int un_blank_pos=0; For(i,n) { scanf("%d",°ree[i]); if (degree[i]^-1) { if (!degree[i]&&n>1){puts("1");return 0;} else if (!degree[i]) {puts("0");return 0;} blank_pos-=(--degree[i]);v[degree[i]]--;un_blank_pos+=degree[i]++; }else T++; } v[n-2]++;v[blank_pos]--; // For(i,n) cout<<v[i]<<' ';cout<<endl; _ans=mul_arr(T,blank_pos); if (un_blank_pos+blank_pos!=n-2) { puts("0");return 0; } // cout<<blank_pos<<' '<<T<<endl; // _ans.print(); For(i,n) { jc=jc+mul_arr(i,1); // cout<<' ';jc.print(); if (v[i]) For(j,n) _ans[j]+=v[i]*jc[j]; // _ans.print(); } // For(i,n) cout<<_ans[i]<<' ';cout<<endl; ans=1; For(i,n) For(j,_ans[i]) ans=ans*i;//,ans.print(); ans.print(); return 0; }
相关文章推荐
- 【BZOJ 1005】 1005: [HNOI2008]明明的烦恼 (prufer数列+高精度)
- 【组合数学】【高精度】【prufer数列】【HNOI 2008】【bzoj 1005】明明的烦恼
- bzoj1005: [HNOI2008]明明的烦恼(prufer数列+高精度)
- BZOJ 1005 [HNOI2008]明明的烦恼 ★(Prufer数列)
- bzoj 1005: [HNOI2008]明明的烦恼(prufer数列)
- BZOJ 1005 [HNOI2008]明明的烦恼 ★(Prufer数列)
- [Prufer数列] BZOJ1005: [HNOI2008]明明的烦恼
- BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)
- bzoj1005: [HNOI2008]明明的烦恼 prufer编码
- BZOJ 1005: [HNOI2008]明明的烦恼(prufer序列->无根树表达)
- 【bzoj1005】 HNOI2008—明明的烦恼
- [bzoj1005][HNOI2008]明明的烦恼-Prufer编码+高精度
- 【BZOJ】1005: [HNOI2008]明明的烦恼(prufer编码+特殊的技巧)
- BZOJ1005 [HNOI2008]明明的烦恼
- [bzoj1005][HNOI2008][明明的烦恼] (高精度+prufer定理)
- 【BZOJ 1005】[HNOI2008]明明的烦恼 【Prufer序列】
- BZOJ1005: [HNOI2008]明明的烦恼
- 【BZOJ 1005】[HNOI2008]明明的烦恼
- [BZOJ1005]HNOI2008 明明的烦恼|prufer编码|排列组合
- bzoj 1005: [HNOI2008]明明的烦恼