BZOJ1211 HNOI2004 樹的計數

2022-08-11 08:15:11 字數 1176 閱讀 2491

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數列中,如果乙個點出...