[Ynoi2003] 戌亥彗星

lalaouye發表於2024-10-18

這個條件有點不好處理,考慮找一些好處理的性質來做這道題。

首先,大體思路是套路的,我們掃描 \(r\),去更新答案,然後我們考慮維護指標 \(l\),我們首先希望區間子圖 \([l,r]\) 有且僅有一個簡單環,考慮用 LCT 維護,具體是維護一棵樹與一條邊,這條邊是多出來的邊,顯然這條邊連著的點都在環內。

而我們現在需要增加一條邊,若我們加入一條邊會產生新的環,我們需要丟掉一些邊,也就是讓 \(l\) 右移,如果右移到多出來的邊,設這條邊為 \(rem\),直接讓 \(rem\) 等於 \(0\) 即可。否則如果刪去 \(E_l\) 時,\(rem\) 可以放入樹中,那麼我們將其放入並讓 \(rem\) 等於 \(0\) 即可。

求出 \(l\) 後,題目要求環以外的點度數都不超過 \(2\),我們可以維護當前擁有的度數超過 \(2\) 的個數和在環內度數超過 \(2\) 的個數,前者直接維護,後者 LCT 維護,由於每刪一條邊可以使前者減少但不一定使後者減少,所以具有單調性,可以直接移動 \(l\)

最後題目要求是連通圖,然而注意到現在我們只有一個簡單環,那麼現在其實是要求 \(|V|=|E|\),由於當前區間 \([l,r]\) 內的區間子圖肯定滿足 \(|V|-|E|\ge 0\),那麼肯定只有 \(|V|-|E|=0\) 時的區間可以產生貢獻,我們可以維護一棵線段樹,每個區間維護 \(|V|-|E|\) 的最小值,在增加貢獻時只有最小值為零的區間可以增加。

然後是一些線段樹和算貢獻的小細節,巨佬可以跳過。由於我們求的是所有區間,所以我們在每個 \(r\) 都增加一次貢獻,然後每個詢問 \(ql,qr\)\(r=qr\) 時算貢獻就行了。

然後就是下傳標記的細節。由於我們會先更新最小值再增加貢獻,所以標記下傳順序應是最小值在先。還有一些維護方法可以看程式碼

時間複雜度 \(\mathcal{O}((n+q)\log n)\)