link
題目大意:
n個節點的帶標號無根樹。每次選擇乙個度數為1的節點並將它從樹上移除。問總共有多少種不同的方式能將這棵樹刪到只剩 1 個點。兩種方式不同當且僅當至少有一步被刪除的節點不同。
題解:先考慮1號店最後移除時候的貢獻,我們可以欽定1號點為根,並欽定他最後移除
然後就是乙個樹形dp
設\(f_i\)表示i號點子樹移除方案數量,\(size_i\)表示1為根時子樹大小
顯然有dp式子\(f_x=\frac\prod f_i\) (滿足1為根時x是i的爹)
然後最後移除點1的情況的貢獻就算出來了
我們考慮換根
先考慮x的轉移少了j這個子樹節點會咋樣
那麼\(f'_x=f_x/f_j/(size_x-1)!*(size_x-1-size_j)!*(size_j)!\)
注意這裡的\(size_x\)是n,我們已經假設x是樹的根了
然後我們再把\(f'_x\)轉移到j上去,則新的j有
\(f'_j=f_j*f'_x/(size_j-1)!*(n-1)!/(n-size_i)!\)
由於涉及到求逆元,時間複雜度為\(o(n\log n)\)
#include #include using namespace std;
const int xkj = 998244353;
int n;
vectorout[100010];
int sz[100010], fa[100010], f[100010];
int fac[100010], inv[100010], ans;
int qpow(int x, int y)
void dfs1(int x)
f[x] = f[x] * (long long)fac[sz[x] - 1] % xkj;
}void dfs2(int x)
}int main()
牛客挑戰賽30 C 小G砍樹 換根
題面 先考慮1號店最後移除時候的貢獻,我們可以欽定1號點為根,並欽定他最後移除 然後就是乙個樹形dp 設fifi表示i號點子樹移除方案數量,sizeisizei表示1為根時子樹大小 顯然有dp式子fx sizex 1 sizei fifx sizex 1 sizei fi 滿足1為根時x是i的爹 然...
牛客挑戰賽30 A 小G數數
思路 先考慮中間b,c的情況,bac,我們先找出所有滿足b,c的情況並存到陣列裡,注意陣列大小 然後,對於每對b,c,求出可以的aa和ad數量,相乘得到針對這對b,c的所有可能 然後所有結果相加。如下 include include include include include include i...
牛客挑戰賽30 A 小G數數
給你乙個1 n的排列a1,a2.ana1,a2.an,問有多少個四元組 a,b,c,d 滿足a b c d且aa示例1 複製4 1 3 2 4複製 1思路 這道題暴力也可做出來,夠毒瘤的,不過暴力是不夠的,應該用dp,定義f i j 表示第j個位置比i小的數的數量,然後雙迴圈遍歷陣列。include...