9.19 abc371補題 & map 在 dp 上的妙用

LCat90發表於2024-09-19

昨天的也一起寫了。

abc371F:兩種做法。等差數列線段樹和 ODT。兩種做法實現難度相同,不過後者似乎要快很多。

花 1 個小時複習了 ODT 怎麼打,他複雜度正確的原因是因為每次 query(l, r) 過後馬上進行了 assign。然後就是基礎的 split 和 getpos 操作,記得給邊界插入 set。

線段樹也是維護三元組 【l, r, pos】 表示左右 id。如果有區間操作的話 lzy 就是 pos 表示等差數列的第一項。每次下傳標記記得去右兒子的時候把 lzy 加 lenLS,然後一個線段樹節點就是由多個等差數列構成。

注意不要寫動態開點的線段樹,非常容易 TLE。


abc317G:這玩意場上想了一半正解。

考慮到正式考試不可能高精度,所以我們使用正常演算法。

這個東西本質上是多個同餘方程合併,每次在合法解裡面貪心選,顯然 lcm 作為模數需要高精度。

注意到如果:\((m_1,m_2)=1\),則必然可以滿足。所以我們要對所有 \(m\) 之間的 gcd 來考慮是否滿足,eg:\(\mod 2 = 1,\mod 4 = 0\) 顯然無解。

又能夠想到質數拆分,如果對於所有質數來判斷一定是等價的。而質數因數個數顯然是亞根號級別。

所以我們順序遍歷每個環,記錄環長 \(l\),然後列舉換上第一個應該是本來的第 \(i\) 個,容易發現這樣子要轉 \(x=l-i\) 次。那麼我們就判斷可行即可。

\(l\) 的所有質因子考慮(這裡考慮所有 \(m_i^{a_i}\) 形式),容易發現等價轉化後 \(x\mod m_i^{a_i}\) 這個值在所有環上都一樣,所以對每個因數記錄一個 mod 值即可。

最後貪心選每個環第一個位置最小的即可。複雜度線性根號,遠遠跑不滿。


[SCOI2013] 數數:經典題。

\(num_i\):以 \(i\) 結尾的所有數的個數。

\(len_i\):……的所有數的長度的和。

\(suf_i\) 以 i 結尾的所有字尾的數的和。

\(q_i\):到 i 的總共答案。

考慮放在遞推形數位 dp 中,加上 0/1 限制數位即可。程式碼細節特別多。


[NOIP2021] 方差:場上估計 60~90min 做出來。

這個操作形式不太規整。觀察到差分過後一次操作就是交換前後的差分值!所以問題就變成了重新排列差分陣列,使得最終的陣列方差最小。

方差拆完之後要維護 sumai 和 sum(ai^2)。

然後我們猜測怎麼排列差分陣列。

注意到差分值單谷 c,這個東西根據我們的暴力跑出來就發現了。
感性理解?肯定是拋物線式的,因為這樣才會平均,畫一下圖就知道單谷顯然更好。

知道這個過後呢,排序過後相當於我們是進行一個插在左右兩邊的區間 dp 了,其實是序列 dp。
wc,dp 狀態裡面記錄 suma,維護 \(\sum ai^2\) 的最大值!這樣就做完了。
dp 從最小的點開始,刷表法轉移。

發現這玩意過不了最後一個點,因為 suma 是 \(nV\) 級別。所以我轉移直接遍歷 map 來轉移可行狀態,發現多一個 log 但是過了。

題解說 \(V << n\),差分值等於 0 的很多,沒有貢獻,所以相當於 n 變成了 V。其實都是省掉了沒用的狀態,好像 map 綜合表現是更優。

打 map 最佳化是因為今天 T4 太神了,從那裡學來的東西。


Mod Mod Mod

首先典:一次有效模運算 /= 2。

然後使用調整法,得知一定存在一個 \(x\) 卡到 \(a_i\) 的上界位置,否則加 1 顯然更優。

於是這就證明了合法的狀態數至多隻有 \(n\log V\) 個。

像上面一樣用 map 記錄 dp 陣列進行轉移,一種是直接 mod ai,一種是直接變成 ai+1 - 1。注意 dp 狀態記錄的是大於等於 \(j\) 的代價和。

注意迴圈的時候要這樣寫:st.erase(it++)。nb 實現。

又不得不提到一道還是 map 的不規則時間複雜度做法的題。


「agc020E」Encoding Subsets

在這裡我們 dp 的狀態是字串

這裡的計數方法是非常典的。不多講。還是欽定最前面一段不是合併型別的合法,後面隨便型別的合法,乘起來即可。

關於不是合併的合法的計算,注意到子集就是迴圈節裡面的字串取 min,此時本來要區間 dp,但是直接字串記憶化掉了,nb。

對了,這個題還用到了兩個函式的相互呼叫,nb。

相關文章