煉石計劃 10 月 04 日 NOIP 模擬賽 #8【補題】 - 比賽 - 夢熊聯盟 (mna.wang)
覆盤
T1 有種 div.2 B 的風格,沒秒,想看題。
T2。只判是否無解?\(k \le 100\)?把 \(200\) 個關鍵連通塊拿出來建圖跑傳遞閉包不就做完了。
一遍過大樣例?簡直不可思議,但還是把 T2 關了吧。
用分析 CF 題的方式分析 T1。發現兩個隔著比較遠的數如果能合併就以為著它們中間隔著的數一定是奇數個。所以它們的下標一定同奇偶。
所以把奇數位置的正數取出來,或把偶數位置的正數取出來,這不就是第一問?第二問的答案難道不是固定?難道不是做完了?
細節有點多,打不是很多。開場 40 分鐘切掉。
對拍啟動。發現第一個點就掛。於是調暴力程式。Two Hundred years later...
T3 T4 好複雜。正解肯定不會的啦。暴力啟動。
最終預期 \(100+100+20+20=240\),實際 T4 爆零了。原因未知。話說為什麼比較複雜的題的爆搜總寫不對呢???
總結
好的:
- 掛分不多(這也算優點???)
- 比較穩,前兩題沒有掛分。
不足:
- 寫對拍時過於不仔細,暴力程式掛了好多次,浪費了很多時間。
- 爆搜經常寫不對。
知識點
- T1:貪心;
- T2:搜尋,圖論,傳遞閉包;
- T3:歸併排序,線段樹(正解用到線段樹但我還沒補出來)。
題解
A. 養蠱神器
首先判掉,如果全是負數,那麼第一問的答案一定是 \(\max a_i\)。對於第二問列舉所有最大值,然後算將兩邊全部清空的步數即可。將長 \(x\) 的全部清空的最小步數是 \(\lfloor x / 2 \rfloor+1\)。
操作二相當於選擇一個長度為 \(3\) 的區間,將其合併為兩個端點的和。
注意到若區間長度為 \(5\),那麼我們可以先對中間三個元素做一次操作,然後將整個區間再做一次操作,也能做到上面的效果——將整個區間合併成兩個端點的和。同理,只要長度為大於 \(1\) 的奇數,都能完成這個操作。
所以我們考慮最終答案的可能的組成,即答案可能是哪些數的加和。不難發現,令最終答案為 \(a_{i_1}+a_{i_2}+\dots+a_{i_k}\)(\(i_1<i_2<\dots<i_k\)),那麼這個答案合法的充要條件是 \(i_1 \equiv i_2 \equiv \dots \equiv i_k \pmod 2\)。
所以我們可以全選奇數位上的正數,或全選偶數位上的正數。這兩者的較大值就是第一問。這裡我們不妨將 \(0\) 也視作正數。
對於第二問,不難發現將 \([i_j+1,i_{j+1}-1]\)(\(1 \le j < k\))內的數刪掉的方案是唯一的,其步數為 \((i_{j+1}-i_j)/2\)。兩側單獨處理即可,與上面全是負數的特判類似。
B. 導航神器
首先 flood fill 求出每個點所在的連通塊。如果有一個傳送門的起點在連通塊-\(x\) 內,終點在連通塊-\(y\) 內,那麼我們連一條邊 \(x \to y\)。然後跑傳遞閉包即可。
但是連通塊數很大,也即圖中點數很大,直接跑肯定不行。注意到傳送門的數量 \(\le 100\),這意味著圖中度不為 \(0\) 的點至多 \(200\) 個。所以只對這 \(200\) 個點跑傳遞閉包,查詢時分討一下是否是關鍵點即可。
C. 擾亂神器
還不會,但是會了 Subtask3,即將每個塊都翻轉。
注意到,將這 \(2^q\) 個長 \(2^{n-q}\) 的塊翻轉,相當於 \(\operatorname{swap}(a_i, a_{i \oplus (2^{n-q}-1)})\),即將 \(i\) 的後 \(n-q\) 位翻轉。考慮將所有的 \(i\) 都執行這樣的操作後,逆序對會發生什麼變化。
不妨將整個序列做一遍歸併排序(或者說畫一顆遞迴樹)。例如當 \(n = 3\):
不難發現,這顆樹上的第 \(d\) 層中,每一個區間所對應的點,在二進位制視角下,從第 \(d\) 位到最高位都全部相同。
所以如果我們要把所有 \(i\) 的後 \(n-q\) 位都翻轉,就意味著這棵樹中,把所有層數 \(\le d\) 的節點的左右兒子互換。例如當 \(n - q = 2\) 時上圖變為:
然後考慮如何處理逆序對。我們令 \(f(d)\) 表示有多少對逆序對 \((i,j)\),使得存在一個層數為 \(d\) 的點,使得其左兒子包含 \(i\),右兒子包含 \(j\)(實際上類似 cdq 分治,考慮每個層數為 \(d\) 的點裡,跨過中點的對的貢獻)。\(g(d)\) 同理表示順序對。那麼將層數為 \(d\) 的所有點的左右兒子交換後,其效果等價於 \(\operatorname{swap}(f(d),g(d))\)。所以預處理 \(f,d\) 即可。顯然答案為 \(\sum f(d)\)。