BZOJ-1211 树的计数
Prufer编码的应用。懒的写质因数分解,直接高精度。
注意当n=1的特殊情况的处理。
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <iostream>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define down(i, l, r) for(int i=l; i>=r; i--)
#define N 234
#define Q 1000000
using namespace std;
int read()
{
int x=0, f=1; char ch=getchar();
while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
int n, d[N], m[N], l;
void Mult(int x)
{
rep(i, 1, l) m[i]*=x;
rep(i, 1, l) m[i+1]+=m[i]/Q, m[i]%=Q;
while (m[l+1]) l++, m[l+1]+=m[l]/Q, m[l]%=Q;
}
void Div(int x)
{
int a=0;
down(i, l, 1) a=a*Q+m[i], m[i]=a/x, a%=x;
while (!m[l] && l>1) l--;
}
int main()
{
n=read();
if (n==1)
{
int x=read(); if (!x) printf("1"); else printf("0"); return 0;
}
rep(i, 1, n) d[i]=read()-1;
rep(i, 1, n) if (d[i]<0 || d[i]>n-2) { printf("0\n"); return 0; }
int a=0; rep(i, 1, n) a+=d[i]; if (a != n-2) { printf("0\n"); return 0; }
m[l=1]=1;
rep(i, 1, n-2) Mult(i);
rep(i, 1, n) rep(j, 1, d[i]) Div(j);
printf("%d", m[l]);
down(i, l-1, 1)
if (m[i]>=100000) printf("%d", m[i]);
else if (m[i]>=10000) printf("0%d", m[i]);
else if (m[i]>=1000) printf("00%d", m[i]);
else if (m[i]>=100) printf("000%d", m[i]);
else if (m[i]>=10) printf("0000%d", m[i]);
else printf("00000%d", m[i]);
return 0;
}

浙公网安备 33010602011771号