csp-s 模擬 12

Qyun發表於2024-10-20

csp-s模擬12

T 小 h 的幾何

whk

我能說什麼呢...

T 小 w 的代數

仙人掌,DP,計數題

本題部分分較有啟發意義

  • 考慮是一棵樹怎麼做
    注意到 \(n\) 比較小,直接想想比較暴力的做法,可以用 \(O(n^2)\) 的複雜度列舉起點和終點,而由於是一棵樹,兩點之間的路徑是唯一的,並且本題要求點集不重,所以這樣就變為了序列問題,即給定一個序列,求給定起始、最終數的上升序列個數,這樣就得到了 \(O(n^4)\) 的做法。注意到列舉終點是一個比較傻的行為,這浪費掉了一些性質,即 \(DP\) 的繼承,所以列舉起點然後 bfs(或dfs) 全域性轉移。時間複雜度為 \(O(n^3)\)

  • 考慮是一棵基環樹怎麼做
    回到上一部份做法,暴力列舉起點和終點,然後發現當起點和終點都在同一棵子樹內時和上一檔無差,而起點和終點不在同一棵子樹時路徑變得不唯一,即在環上有分叉,對於現在這個做法當然也就是多列舉一遍的事,但是注意兩次轉移都會有不選環上其他的點直接選終點的轉移,而這樣的轉移實際上是多轉移了一次,用環上起點轉移一次減掉即可。還是想想怎麼 bfs 最佳化,注意到從路徑本質上是 一棵子樹 \(\to\)\(\to\) 另一棵子樹,在進入另一棵子樹前將兩條路徑的狀態合併即可。具體的,先列舉起點,當 bfs 到環上時先將環上的點全部轉移完畢再繼續,關於轉移可以正反跑兩圈,每到達一個點就將 \(O(n)\) 狀態記錄下來,這樣一個點就有正反兩個狀態,考慮合併,注意到包含了環上起點的狀態兩次,直接 \(O(n)\) 合併後 \(O(n)\) 減掉即可。
    這樣時間複雜是 \(O(n^3)\)

  • 考慮是一顆仙人掌怎麼做
    將環看作點仙人掌本質上是一棵樹,可以套用上面的做法,而環上就特殊轉移(將環上的點兩遍轉移完後再進行下一步)就行。具體的,先列舉起點,點轉移是平凡的,當到一個環上時和處理基環樹一樣正反轉移兩次、合併狀態、去重即可。
    時間複雜為 \(O(n^3)\)

T 小 y 的數論

結論題,樹論,st表

  • 結論 1:兩個點集合並後直徑的兩個端點一定是屬於原來兩個點集直徑共四個點中的。
    證明:考慮反證法以及 dfs 找直徑。

  • 結論 2 :定義一個點集選 \(k\) 個點構成虛樹的邊權最大值的這 \(k\) 個點為前 \(k\) 優點,兩個點集合並後的前 \(k\) 優點一定是屬於原來兩個點集的前 \(k\) 優點的。
    證明:和結論 3 一起證明。

  • 結論 3:前 \(k\) 優點一定是包含前 \(k-1\) 優點的。
    證明:先考慮對於一個點集怎麼怎麼獲得這前 \(k\) 優點,首先這個點集的直徑一定是會被選入的,然後欽定直徑的一個端點為根對這個點集進行長鏈剖分,(算上重鏈頂部的輕鏈)從大到小選擇前 \(k-2\) 大即可,依據貪心這樣肯定是對的。這個地方就能證明出結論 3 了。現在考慮對於兩個點集的合併,根據上述方法,新點集的直徑一定是會被選擇的,如果 k>2 ,則接下來的兩條邊一定是優先選擇以原直徑為端點的長鏈,那麼剩下的鏈就變成了原來的形態了(原兩個點集的重鏈),則剩下的一定在這些中選擇,證畢

根據結論 2、3,我們能得到一個顯然的線段樹做法,即每個區間維護這個區間的前 \(k_{max}\) 優點,合併就長剖按照上述方法即可(不懂題解為什麼能 \(O(n)\),不排序就能求前 k 長鏈嗎?求教教)。時間複雜度為 \(O((n+q)lognk_{max}logk_{max})\) ,並且這個做法常數巨大會 GG。考慮最佳化,注意到合併兩個點集的前 k 優和區間取最小值、最大值、\(\gcd\) 是一個道理(即可重複貢獻類問題),所以可以 \(st\) 最佳化。具體的每 \(k_{max}\) 分成一個塊,共有 \(O(\frac{n}{k_{max}})\) 塊,預處理是 \(O(nlogk_{max}log\frac{n}{k_{max}})\) 可以接受。而查詢可以將散塊合併成一個塊再和 st 表中的兩個塊合併即可,這部分的時間複雜度為 \(O(qklogk)\) 的。

但是這樣的話可能還是不太好過,可以將 st 表中的 k 個點有序放置,這樣合併的時候就能歸併省去一次排序,然後建虛樹時用單調棧能再省去一次排序,這樣就能過了。
總時間複雜度為 \(O(nlognlogk+qklogk)\)

T 小j 的組合

簽到題

以直徑的兩個端點分別作為起點和終點即可,證明略。

時間複雜度 \(O(n)\)

相關文章