标签:
[BZOJ1005][HNOI2008]明明的烦恼
试题描述
自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在
任意两点间连线,可产生多少棵度数满足要求的树?
输入
第一行为N(0 < N < = 1000),
接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
输出
输入示例
3 1 -1 -1
输出示例
2
数据规模及约定
见“输入”
题解
知道 prufer 序列这题就是删边题了。这题不仅要写高精度,还不能随便用除法,使劲压常数,组合数要分解质因数才能过!!
= =就当练高精度吧。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = Getchar(); }
return x * f;
}
#define maxn 1010
int n, deg[maxn], cnt;
struct bign {
int len, A[5010];
bign() { len = 1; memset(A, 0, sizeof(A)); }
bign operator = (const int& t) {
len = 1; A[0] = t;
while(A[len-1] > 9) A[len] = A[len-1] / 10, A[len-1] %= 10, len++;
return *this;
}
void clear() {
for(; !A[len-1] && len; len--) ;
if(!len) len = 1;
return ;
}
bign operator * (const int& t) const {
bign ans; ans.len = len;
memcpy(ans.A, A, sizeof(A));
for(int i = 0; i < len; i++) ans.A[i] *= t;
for(int i = 0; i < len; i++) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
int j = len + 1;
for(; ans.A[j-1] > 9;) ans.A[j] += ans.A[j-1] / 10, ans.A[j-1] %= 10, j++;
ans.len = j;
ans.clear();
return ans;
}
bign operator *= (const int& t) {
*this = *this * t;
return *this;
}
bign operator * (const bign& t) const {
bign ans; ans.len = len + t.len - 1;
for(int i = 0; i < len; i++)
for(int j = 0; j < t.len; j++) ans.A[i+j] += A[i] * t.A[j];
for(int i = 0; i < ans.len; i++) ans.A[i+1] += ans.A[i] / 10, ans.A[i] %= 10;
int j = ans.len + 1;
for(; ans.A[j-1] > 9;) ans.A[j] += ans.A[j-1] / 10, ans.A[j-1] %= 10, j++;
ans.len = j;
ans.clear();
return ans;
}
bign operator *= (const bign& t) {
*this = *this * t;
return *this;
}
bign operator - (const bign& t) const {
bign ans; ans.len = len;
memcpy(ans.A, A, sizeof(A));
for(int i = 0; i < len; i++) {
if(i < t.len) ans.A[i] -= t.A[i];
if(ans.A[i] < 0) ans.A[i] += 10, ans.A[i+1]--;
}
while(!ans.A[ans.len-1]) ans.len--;
return ans;
}
bign operator -= (const bign &t) {
*this = *this - t;
return *this;
}
bign operator / (const bign& t) const {
bign ans, f; f = 0; ans.len = -1;
for(int i = len - 1; i >= 0; i--) {
f *= 10;
f.A[0] = A[i];
while(f >= t) {
f -= t;
ans.A[i]++;
if(ans.len == -1) ans.len = i + 1;
}
}
return ans;
}
bool operator >= (const bign& t) const {
if(len != t.len) return len > t.len;
for(int i = len - 1; i >= 0; i--) if(A[i] != t.A[i]) return A[i] > t.A[i];
return 1;
}
void print() {
for(int i = len - 1; i >= 0; i--) putchar(A[i] + ‘0‘);
return ;
}
} ;
int prime[maxn], cp;
bool vis[maxn];
void prime_table() {
for(int i = 2; i <= n; i++) {
if(!vis[i]) prime[++cp] = i;
for(int j = 1; j <= cp && i * prime[j] <= n; j++) {
vis[i*prime[j]] = 1;
if(i % prime[j] == 0) break;
}
}
return ;
}
bign Pow(int a, int n) {
bign sum, t; sum = 1; t = a;
while(n) {
if(n & 1) sum *= t;
t *= t; n >>= 1;
}
return sum;
}
int Cp[maxn];
bign C(int n, int m) {
for(int i = 1; i <= cp; i++) Cp[i] = 0;
for(int i = n; i >= n - m + 1; i--) {
int tmp = i;
for(int j = 1; j <= cp; j++) if(tmp % prime[j] == 0)
while(tmp % prime[j] == 0) Cp[j]++, tmp /= prime[j];
}
for(int i = m; i; i--) {
int tmp = i;
for(int j = 1; j <= cp; j++) if(tmp % prime[j] == 0)
while(tmp % prime[j] == 0) Cp[j]--, tmp /= prime[j];
}
bign sum; sum = 1;
for(int i = 1; i <= cp; i++) if(Cp[i]) sum *= Pow(prime[i], Cp[i]);
return sum;
}
int main() {
n = read();
prime_table();
int tot = 0;
bool ok = 1;
for(int i = 1; i <= n; i++) {
int x = read();
if(x >= 0) deg[++cnt] = x - 1, tot += (x - 1);
if(!x) ok = 0;
}
if(!ok || tot > n - 2) return puts("0"), 0;
tot = n - 2;
bign sum; sum = 1;
for(int i = 1; i <= cnt; i++) {
sum *= C(tot, deg[i]);
tot -= deg[i];
}
sum *= Pow(n - cnt, tot);
sum.print(); putchar(‘\n‘);
return 0;
}
除法的定义其实没用,我第一次用了除法 T 飞了,现在懒得删了。
标签:
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/5743709.html