CF 2001 E2
由於對稱,所以設 \(heap[u]\) 為兩次確定堆,且第一次彈出的是 \(u\),\(heap[u,v]\) 是第一次 \(u\) ,第二次 \(v\)
則答案就是 \(\sum heap[u]=2^{n-1}·heap[x]\)
其中 \(x\) 任意。
不妨我們考慮第一次都是從第一個葉子彈出,那麼對於其他不同的第二個彈出的點,根據對稱性顯然有如下性質:
\(LCA(u,v_1)=LCA(u,v_2)\implies heap[u,v_1]=heap[u,v_2]\)
而經過手玩一下關係,可以發現:
也就是設 \(L_1,R_1\) 是兩個葉子的 \(LCA\) 的左右兒子,\(l,r\) 是 \(L_1\) 的左右兒子(圖稍微畫錯了點)
容易得到:
而對於更上層的點,還是設當前點左右兒子是 \(L_1,R_1\),\(L_1\) 的兒子是 \(l,r\),則有:
由 E1,我們求出了 \(f_{i,j}\):高為 \(i\) 的堆,操作 \(j\) 次,只彈出第一個葉子的方案數,以及 \(g_{i,j}\):操作 \(j\) 次的總局面個數
借用一張官解的圖
我們會發現 \(L,R\to L'\) 的時候,\(R\) 是普通子樹,而 \(R'\) 是一顆滿足彈一次合法的子樹。
所以 \(L'\) 的方案數可以由符合條件的 \(L,R\),\(f_{L}·g_R\) 構成,而總的方案數需要再用 \(f_{R'}\) 進行合併。
而用 \(f_{R'}\) 合併的時候要乘上 \(2^{h-2}\) 因為葉子任選其一。
而也有可能自身不是 \(LCA\),往上更新的時候直接算就行了,注意要拼上一個普通二叉堆個數。
所以可以設 \(dp_{h,l,r}\) 為高為 \(h\) 的樹,左子樹權值 \(l\),右子樹權值為 \(r\) 的方案數。
那麼有:
可以利用字首和最佳化到 \(O(nk^2)\),例如前半部分,可以設 \(S_{x,y}=\sum_{l,r}f_{h-2,l}·g_{h-2,r}·[l+r=x][l=y][l>r]\),先做 \(y\) 這一維的字首和,再做 \(x\) 這一維的字首和即可。
後半部分同理。
code