portal
乙個有\(n(n\leq150)\)個結點的樹,給出每個節點的度數\(d_i\),求滿足度數要求的無根樹的個數。
簡單來說,一棵\(n\)個節點的無根樹與乙個數值在\([1,n]\)的長度為\(n-2\)的序列一一對應,這個序列便稱作prufer數列。其中若點\(i\)的度數為\(d_i\),那麼\(i\)在prufer數列中就出現\(d_i-1\)次。
那麼這道題就很簡單了:向乙個長度為\(n-2\)的序列中填入\(d_1-1\)個\(1\),\(d_2-1\)個\(2\),...,\(d_n-1\)個\(n\)。
\[\begin
ans &= \binom \binom ...\binom^(d_i-1)} \\
&= \frac \cdot \frac^2(d_i-1))} ... \frac^(d_i-1))!} \\
&= \frac^n (d_i-1)!}
\end$$由於階乘比較大而且坑爹的不取模,所以通過分解質因數的方法來計算。
> 時間複雜度$o(n^2)$。
##code
```cpp
//[hnoi2004]樹的計數
#include int const n=200;
int n,d[n];
int fac[n][n];
void init()
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) fac[i][j]+=fac[i-1][j];
}int ansp[n];
int main()
}if(sum!=n*2-2)
if(n==1)
for(int i=1;i<=n;i++) ansp[i]=fac[n-2][i];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) ansp[j]-=fac[d[i]-1][j];
long long ans=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=ansp[i];j++) ans*=i;
printf("%lld\n",ans);
return 0;
}```
##p.s.
注意要特判掉無解和$n=1$的情況。\]
bzoj 1211 HNOI2004 樹的計數
題意 給出每個節點的度數,問有多少棵樹滿足這些度數。題解 pr fer序列 組合數學 pr fer序列是由標號樹產生的唯一數列。生成方法 一棵樹要得到普呂弗序列,方法是逐次去掉樹的頂點,直到剩下兩個頂點。考慮樹t,其頂點為。在第i步,去掉標號最小的葉,並把普呂弗序列的第i項設為這葉的鄰頂點的標號。序...
BZOJ 1211 HNOI2004 樹的計數
今天早上由於剩下的非許可權題實在是太難了。於是學了一下新東西續命。直接prufer序列排列組合就好了。注意各種0的情況 code include include typedef long long ll const ll n 155 ll n ll a n ll pri n ll tot ll cn...
bzoj1211 HNOI2004 樹的計數
題目傳送門 解法 prufer數列。有這麼三個性質 乙個prufer數列與乙個無根樹一一對應。乙個n個節點的無根樹的prufer數列長度為n 2。乙個點的度數等於他在prufer數列裡面出現的次數 1。第三個性質這樣證明 首先需要了解prufer序列如何構造 看這裡在prufer數列中,如果乙個點出...