動態規劃:可以認為由狀態,轉移兩個過程構成
樹上最佳化技巧
P1272 重建道路
設,dp[i][j]為包含i的大小為j的連通塊的最小操作次數,列舉i的每個子樹一個個合併上去。
考慮兩個點i,j只會在lca處有計算時間貢獻,所以是\(O(n^2)\)的
LOJ160. 樹形揹包
先跑dfs序,設dp[i][w]為從第i個位置開始的字尾,容量為w的最大價值。
設第i個位置為x,則\(dp[i+1][w-w[x]]\)可以轉移過來。
或者直接跳過\(x\)所在的子樹,從\(dp[low[x]+1][w]\)轉移過來。
多項式最佳化(拉插)
首先可以高斯消元,\(O(n^3)\)
然後考慮其實可以構造,詳見拉格朗日插值法
自然數冪和
拉插經典應用
\(F(k)=\sum_{i=1}^{n}i^k\),求\(F(k)\)
\(k<=2000,n<=10^9\)
令\(f(x)=x^k\)
考慮計算\(f(x)-f(x-1)=x^k-(x-1)^{k}\)
將\((x-1)^k\)二項式展開,發現\(f(x)-f(x-1)\)的\(k\)次項正好沒了,所以\(f(x)-f(x-1)\)是\(k-1\)次的。
對\(f(x)-f(x-1)\)求和,我們知道對一個\(y\)次的多項式\(g(x)\)求\(\sum_{i}g(i)\)是\(y+1\)次的。
所以\(\sum_{i=1}^{x}(f(x)-f(x-1))\)是\(k\)次的,即\(f(x)\)是\(k\)次的。
再做一次,所以\(F(x)=\sum_{i=1}^{x}f(x)\)是\(k+1\)次的。
然後拉插。
CF1967C Fenwick Tree
考慮列舉區間結尾x,取出長度為\(lowbit(x)\)的一段,區間內每個點到終點的貢獻係數的多項式(自變數為k)是\(log(n)\)級的,因為貢獻路徑長度為\(log(n)\)量級。
所以最後每個位置必定是一個對k的O(log) 階多項式,所以直接暴力跑前 log 次,然後對每個位置都插一遍就做完了。
P8290 [省選聯考 2022] 填樹
極差小於等於\(K\)不好做,考慮列舉最小值權值\(x\),那麼所有路徑上的點的權值都要在\([x,x+k]\)內,現在每個路徑上的點\(i\)的權值範圍是\([max(x,l_i),min(x+k,r_i)]\)。
先思考如何暴力,我們顯然只關心每個點權值範圍的大小,也就是\(max(0,min(x+k,r_i)-max(x,l_i)+1)\)。
於是可以直接列舉路徑,把路徑上所有範圍大小乘起來即可。
但是發現有一個問題,這樣做不能保證最小權值為\(x\),可以計算所有路徑上的點權值在\([x+1,x+k]\)內的答案,簡單容斥掉。
考慮最佳化,計算範圍的時候有\(min\)和\(max\),這樣十分的不好計算,對每個點分類討論一下。
P10013 [集訓隊互測 2023] Tree Topological Order Counting
首先考慮計算一個子樹的合法拓撲序數量。
假設一個點x有兩個兒子a和b,dp[i]為i子樹內拓撲序的數量。
不難發現有\(dp[x]=dp[a]\times dp[b] \times C(sz(a)+sz(b),sz(a))\),可以理解為siz(x)個位置內隨便選取siz(a)個位置把一個a的拓撲序順序放進去,剩下的位置把一個b的拓撲序順序放進去。
如果x有很多個兒子也是一樣的,手推一下不難得出,比如有一個兒子c,就乘上\(dp[c] \times C(sz(a)+sz(b)+sz(c),sz(a)+sz(b))\)$。
把組合數拆一下,最終的方案數就是sz總和的階乘除以每個sz各自的階乘。
sz總和顯然是\(sz(x)-1\),即分子為\((sz(x)-1)!\),發現x在計算其父親的答案的時候會貢獻一個\(\frac{1}{sz(x)!}\)。
所以以x為根的拓撲序數量為\(\frac{sz(x)!}{\prod_{y}sz(y)!}\),其中y是x的兒子。
設f[x][i]表示x的子樹內的拓撲序,表示s在x子樹的拓撲序的第i位的方案數,其中s是題目中列舉的u,然後把s到根的一條鏈上的點跑樹形dp。
不難得出,f[s][1]=dp[s]。
考慮怎麼把一個點y的資訊轉移到父親x,我們可以先計算除了y的x的所有的兒子的拓撲序方案數,,根據前面的結論,只需要預處理x個每個節點z的\(\frac{1}{sz(y)}\)然後把y的siz(y)的拓撲序和這個長度為\(sz(x)-sz(y)-1\)的拓撲序合併。
如果現在s在y的拓撲序中的位置為i,列舉長度為\(sz(x)-sz(y)-1\)的拓撲序中有j個在s之前,方案數為\(C(i+j-1,i-1)\times C((siz(x)-1)-i-j,sz(y)-i)\)
別忘了x一定要放在其子樹拓撲序的第一位,所以\(f[i][j]\)一定要變成\(f[i][j+1]\)
根據一開始重建道路這道題的分析,單次是\(O(n^2)\)的,總時間複雜度為\(O(n^3)\)
對於點s,答案為\(\sum{i=1}^(n)f[1][i]\times b[i]\)
考慮將整個過程從上往下推,假設已知\(f[x][i]\),怎麼向下計算。
可以把\(f[i][j]\)的值該為s在\(x\)子樹內的第i個位置,向上的貢獻是多少
最小斯坦納樹
模板:P6192 【模板】最小斯坦納樹
首先分析為什麼形成一棵樹是最優的,顯然如果出現環刪掉任意一條邊都會更優,所以選出來的是一棵樹。
從小往大列舉一個關鍵點集S