「LG P1393」Mivik 的標題
題目鏈接:洛谷。
設 \(L=|S|\),設 \(s\) 為所謂名字的字符串。
前半部分算是非常套路。設 \(f_k\) 表示隨機生成一個長度為 \(k\) 的字符串后,它的一個后綴為 \(s\),且 \(s\) 為第一次出現的概率。
不難發現答案就是 \(\sum_{k=1}^{n}f_k\)。這個狀態的轉移也是套路的容斥,也就是去容斥“第一次出現”。我們首先要保證沒有 \(s\) 的結尾位置落在 \([1,k-L]\) 之間,那么此時任意組合的概率就是 \((1-\sum_{j=1}^{k-L}f_j)\times m^{-L}\)。
接着對於結尾在 \((k-L,k)\) 的 \(s\) 進行容斥,對於每一種不合法的情況,我們在第一次重復出現 \(s\) 的位置那里容斥掉它。前面已經保證了在 \(k-L\) 之前不會有 \(s\) 結尾,因此之前的貢獻可以用 \(f\) 計算。假設相交的長度為 \(l\),則貢獻應當為 \(-f_{k-L+l}\times m^{-L+l}\),並且還需要滿足 \(s[1:l]\) 是 \(s\) 的一個 Border。
現在其實已經可以將問題寫成多項式形式並使用半在線卷積計算答案了。不過,我們可以將 Border 划分為 \(O(\log L)\) 個等差數列,這樣每個等差數列中的 \(-f_{k-L+l}\times m^{-L+l}\) 可以直接前綴和維護,最終只需要維護 \(O(\log L)\) 組前綴和即可優化轉移。
小結:
- 注意這類問題的通用 DP 形式;
- 注意使用等差性質優化轉移的思想;
「LOJ569」Misaka Network 與測試
題目鏈接:LOJ。
就那么一個點要說的:我們總是優先選最小的滿足要求的矩形。這個原則很容易推斷出“單獨選 2
格子”,但是很容易忘記這可以往后退一步——選完所有 2
之后,如果 1
和 3
相鄰,那么就可以直接選走。按照這種方法選完之后就不可能剩下更多的滿足要求的矩形了,因此可以直接跑二分圖匹配。
小結:思考要足夠深,想的時候稍微多想那么一步嘛。
「ARC103B」Robot Arms
首先思考無解的情況:不妨設我們對於 \(S\) 之中的操作,將 \(d\) 的權值賦成了 \(-1\)。由於 \(x+y=\sum_i(-1)^{[i\in S]}d_i=\sum_id_i-2\sum_{j\in S}d_j\),所以所有 \(x+y\) 的奇偶性必須相同我們才可以構造出來。相應地,我們嘗試在其它情況下構造出解。
這個問題,稍微擺弄一下就會覺得有一點比較奇怪:明明是上下左右四個方向移動,為什么一次操作對於某一維來說 +1,-1,0 有三種系數?這其實還是系數之間不是獨立分配的原因。我們讓系數獨立開來,也就是每一維上要么是 +1,要么是 -1。這個可以直接通過將坐標軸旋轉 \(45^\circ\) 並縮放達成。
各維獨立之后,整個問題就變得容易許多。類似於無解情況的構造方法,這個問題本質上就是湊數的問題,直接按照二進制配每一位即可。此外還有一點點化歸想法:\((x+y)\bmod 2=1\) 的情況比 \((x+y)\bmod 2=0\) 的情況,我們於是加入一個長度為 1 的機械臂來調整即可。
小結:熟悉平面上常見的空間變換方式,同時多嘗試一下獨立變量。
「CF1267G」Game Relics
這道題比較需要觀察能力。首先考慮任意一個購買方案,可以發現兩點:
-
每當我們開始隨機,我們就一定會隨機到新的物件才停止此輪隨機,否則這(幾)次隨機都是無效的;
根據這一點,我們可以用物件的全排描述一種購買情況,按物件來划分。
-
當我們開始按原價購買時,我們之后都不會再進行隨機。
已有物件越多,隨機到新的物件概率越小;相應地,花費越高,所以先隨機一定不劣。
根據期望的線性性,我們可以將整個方案的期望花費,拆分為每買一個新物件的期望花費。因此考慮手頭上有 \(k\) 件、未得到的價值和為 \(s\) 時的抉擇。此時隨機的期望花費為 \(\frac x 2(\frac n k + 1)\),而隨機時期望占便宜為:
因此可以看作期望花費 \(\frac x 2(\frac n k + 1)\) 和 \(\frac s {n-k}\) 選一個,直接選小的即可。剩下的就是一個簡單的背包了。
小結:
- 使用交換等方式分析決策性質;
- 利用期望的線性性來拆開決策過程,便於日后計算;
「UOJ671」詭異操作
題目鏈接:UOJ。
操作一直接勢能線段樹維護,注意特判 \(v=1\),此外無甚可說;
操作二處理起來比較妙。一種方法是按位獨立,各開線段樹處理。但是這種處理方式不方便與操作一整合,因此我們也可以開一棵線段樹,同時對於 128 位的每一位,記錄當前位為 1 的個數和 and
標記。當然,這樣做的復雜度為 \(O(\log V(q\log n+n\log V))\),下輩子也過不了。
下面就是奇妙的想象了:我們在一個長度為 \(L\) 的結點上,存了 128 個值,這些值的值域為 \([0,L]\)。但如果我們將這些值轉化成二進制,我們不就在存儲一個 \(128\times \log L\) 的 01 表嘛?為了更好地壓榨計算機利用二進制運算特性,我們可以轉換存儲方式,用 \(\log L\) 個 __int128
存表而非 128 個 int
存。這樣合並信息的復雜度降到了 \(O(\log L)=O(\log n)\)。
分析復雜度:操作一至多造成 \(O(\log V)\) 次每個結點的重構,因此復雜度為 \(O(\log V\sum \log L)=O(n\log V)\),而操作二可以直接視作 \(O(q\log^2 n)\),總復雜度即為 \(O(n\log V+q\log^2 n)\)。
小結:
- 觀察問題的角度很重要。首先當然需要找出問題的結症,而后是從多個角度去觀察,開拓思路才可能解決。當然這里的處理也可以看作是“平衡復雜度”的操作;
- 高維數組尋址很慢,如果數組很大很常用,就用內存池;
「POJ1927」Area in Triangle
題目鏈接:POJ
設 \(l\) 為繩長,\(c_r\) 為內切圓周長,\(c_t\) 為三角形周長。
當 \(l\le c_r\) 或 \(l=c_t\) 的時候都很簡單,略過。
關鍵在於怎么處理 \(c_r<l<c_t\) 的情況。可以想象在三角形里面塞了一個氣球,往里頭充氣的時候氣球會膨脹。不難發現在同等體積下氣球傾向於保持表面積最小的形態,因此一頓 yy 之后就能想象出最終的形狀為:
最后氣球的形狀就是 \(OM,\overset{\Large \frown}{MI},IK,\overset{\Large \frown}{KH}, HL, \overset{\Large \frown}{LJ}\) 這么圍起來的一個封閉圖形。相應的,我們要做的就是通過周長算出相應的面積。
注意到三個圓弧對應的曲率半徑相同,因此我們很容易算出這個曲率半徑。得到曲率半徑之后,我們發現可以通過割補將三個扇形集中到一個圓形中,所以整個的面積就是 \(S_{大三角}+S_{小圓}-S_{小三角}\)。
小結:
- 解決幾何的最優問題,通過合理的轉化得到物理模型,再發揮想象,不失為一種好方法;
- 常用的平面幾何技巧需要多積累,最怕的是知道但不會用......
「CEOI2010」Alliances
題目鏈接:LG。
也是一道有一點小技巧的網絡流題目,實在是太久沒有做過網絡流了......
問題主要出現在翻譯題目上——如何將題目轉化為等價的描述?這個題目中最難搞的“人類限制”,實際上就等價於:上下、左右各自最多只能同時貢獻 1 的流量!
當然也可以用 exclusion 的方式看待它:例如上下同時存在時,上下同時貢獻了 2 的流量。而注意到上下、左右是互斥的,所以我們只需要保證上下不同時貢獻 2 即可,左右類似。
「Gym102956D」Bank Security Unification
題目鏈接:CF。
不套路的清新 DP 題。講真這種類型的題目真真是我的弱項......
不難想到一個暴力的 DP,用 \(g_{k}\) 表示 \(f_k\) 作為序列中最后一個元素的最大序列權值。
說起位運算,我們常常可以聯想到按位考慮。這題可以類似嗎?看起來很勸退?
一般來說,DP 優化要么是合並狀態,要么是踢狀態。合並顯然不現實,我們要“踢”,就得進行比較。在計算 \(g_k\) 的時候,考慮 \(i<j<k\),且在 \(f_{i},f_{j},f_{k}\) 中都包含某一個 \(2^t\)。則我們比較 \(i,j\) 的時候可以發現,同時選上 \(i,j\) 一定比只選 \(i\) 優。於是同時包含某一個 \(2^t\) 的轉移點,我們只需要考慮一個。對於所有的 \(t\) 動態維護一個最靠后的點即可。最終優化到了 \(O(n\log f)\)。
小結:DP 的優化要么是合並相似狀態,要么是剔除劣狀態;此外還需要考慮切入點,比如在位運算的背景下,按位考慮就是一個始終值得下手的口子。
「CF1146F」Leaf Partition
題目鏈接:LG。
可以發現,所謂 \(f(L)\) 其實就是 \(L\) 點集生成的虛樹。
我們可以從底向上考慮問題:先將每棵葉子單獨划分進某個集合,而后在每個結點上考慮合並某些集合——這個過程顯然易於列 DP。這個過程中,我們不妨認為我們在動態維護虛樹,所以可以列兩個狀態:\(f_{u}\) 表示將 \(u\) 子樹內的葉子划分入若干個集合的合法方案數,而 \(g_{u}\) 表示,所有不同的虛樹形態的個數。
\(g\) 狀態是為了解決這樣的問題:如果 \(u\) 沒有被覆蓋,且 \(u\) 的子樹內有多棵可以向上延伸的虛樹;則在 \(f_{u}\) 內這種情況只會被計算一次,但如果在 \(u\) 的祖先處 \(u\) 被覆蓋,那么它的子樹內的虛樹是不能看作同一棵的,因此需要多計算幾次。
\(g\) 實際包含了兩種情況:
- \(u\) 成為了某棵虛樹的根;
- \(u\) 不是某棵虛樹的根,此時我們需要從它子樹內可以向上延伸的虛樹中,選擇一棵並將它的根一路上提到 \(u\)(並將路上的結點也算在那棵虛樹中)。如果選擇的虛樹不同,則即便划分方式相同也會被算多次。這也就是所謂“虛樹形態的含義”;
小結:自底向上動態維護虛樹的 DP 還是挺有意思的。
「CF285E」Positions in Permutations
題目鏈接:LG
首先,這道題的難點之一是不要讀錯題目。
注意題目中 beauty 定義為兩兩差最小值,所以這個東西與順序無關,序列可以被排序。之后,我們嘗試枚舉 beauty 值計算相應的序列個數。計算序列個數可以做到 \(O(nk)\),不多說。關鍵在於,我們發現beauty 值的值域其實並不大。排序后可以分析出,beauty 的一個上界為 \(\frac{\max a}{k-1}\),因此復雜度為 \(O(n\max a)\)。
平時對數值就不是很敏感,對於這種值域明顯比較小的問題一定要注意值域信息。如果確實分析不來,直接用其它方法剪枝,可能也會得到正確的復雜度。
「JSOI2019」精准預測
題目鏈接:LG
顯然可以構建按照 2-SAT 的方式構圖。(需要注意,題目別讀錯了!!!)
壓縮后,圖的大小是 \(O(m+n)\) 的。對於某個人 \(k\),他實際上只有兩個需要注意的點:\(a_k\) 和 \(d_k\)。我們需要解決:
- \(a_k\) 能否到達 \(d_k\)?
- \(a_k\) 能到達多少個 \(d_j\),\(j\not=k\)?
可達性問題顯然可以使用 bitset
來處理,問題是直接做空間復雜度為 \(O(\frac{n(n+m)}{\omega})\)。
注意到,\(d_j\) 之間是相互獨立的。為了平衡,我們可以分成若干次詢問,每次處理的關於所有 \(d_j,j\in [l,l+S)\) 的問題。
這也是類似於復雜度平衡的思想,只不過是平衡時間與空間。這也是一種離線的處理方法,事實上 Methods of Four Russians 中,也有不少可以類似的離線處理、壓縮空間。
「Gym 101630J」Journey from Petersburg to Moscow
題目鏈接:Gym。
顯然可以直接枚舉一個閾值 \(t\),而后假裝所有 \(\ge t\) 的邊在路徑上都得收費,而 \(<t\) 的就不用收費了。暴力做需要記錄經過了多少條需要收費的邊,復雜度為 \(O(mn^2\log n)\)。
可以想到用 WQS 二分來將一個 \(n\) 換成 \(\log V\)。二分一個 \(\delta\),對於 \(\ge t\) 的邊,全部減去一個 \(\delta\)。為了避免出現負數,我們控制 \(\delta \le t\)。可以發現這樣並不會出錯,因為如果 \(\delta=t\) 之后都還沒有出現合理的路徑,那就說明這個 \(t\) 實在是太劣了。
但當我們想到了“減法”這種技巧的時候,我們只需要再深入一步——對每條邊都減去閾值 \(t\),並對 0 取 \(\max\)。這樣跑 Dijkstra 之后,再加上 \(kt\),就一定不會多算答案。
我們其實只需要保證某些 \(\ge t\) 的邊數量不足 \(k\) 的路徑不會被錯誤地計入答案即可。首先,這些路徑會在對應的 \(t'\) 的枚舉情況中計算到。而此時這些路徑上作為前 \(k\) 大的某些邊,它們的權值會變大,因此計算長度長於實際長度,沒有影響。
小結:求最值簡化問題無非兩個角度:弱化限制或者縮小搜索空間——這道題用的就是前者。但想到這個“減法”的方向可能還是需要動一下腦筋,最好留個印象!
「SDOI2017」天才黑客
題目鏈接:LG。
這道題雖然被放在了這里,但是它實際上真的一點一點一點也不“袖珍”。
把題目讀懂之后就會明白這道題的方向是優化建圖。
第一個步驟,如果真真暴力的話會建出來 \(O(nk)\) 個點,肯定沒法做。但是仔細一想就會發現,某種口令在結點 \(u\) 處有效,當且僅當這個口令在任意一條鄰接邊中出現過。因此有效的狀態個數馬上被壓縮到 \(O(m)\) 種。
第二個步驟,如果暴力一點,在某個結點處,對於所有口令狀態交叉連邊,那么可能會連出 \(O(m^2)\) 條邊然后爆炸。不過,由於這道題有 Trie 的背景,因此可以想到在 Trie 上進行優化的動作——Trie 上兩個字符串的 LCP 為 LCA 的深度。如果對於每個結點都復制一棵 Trie 當然也會爆炸,不過既然邊權只和結點深度有關,因此可以想到用虛樹壓縮。
由於某些原因,我們必須保證連出來之后路徑上邊權恰好經過 LCA。那么考慮兩種情況:
- LCA 為端點,這個時候可以直接樹上前后綴;
- LCA 不為端點,此時可以枚舉 LCA,並保證必須在跨子樹的時候才能進行貢獻——顯然可以直接對於兒子進行前后綴優化。
小結:
- 點太多的時候要主動去壓縮狀態;
- 這里關於 LCA 的建圖還是挺有意思的;
「聯合省選 2020 A」樹
還是挺有意思的,用到的算是一個 Trie 的小技巧。
我們需要維護全局 +1 之后的全局異或和。研究一下,發現 +1 就是將最后一段 1 全部翻成 0,然后再將后面跟的 0 變成 1。不過,一個遞歸的視角可以展現更多的東西:
如果 \(x\) 是奇數,則 \(x+1\) 為偶數,且恰好為 \(\lfloor\frac x 2\rfloor\) +1 后的結果再 \(\times 2\);否則,結果就是 \(x+1\)。
Trie 上,偶數 +1 直接調換兒子即可;而奇數 +1 可以如上遞歸調換右兒子。所以,最終復雜度可以做到 \(O(n\log n)\)。
「SDOI2013」保護出題人
題目鏈接:LG。
看到“除法”,就應該想到兩點間斜率這個備選項。
想到最大化斜率,就不難想到上凸包優化了。
「SDOI2014」LIS
這題還是有一個要點的:關於最小割的可行邊和必須邊的問題。
可行邊:對於一條邊 \(e\),如果存在一個割邊包含 \(e\) 的最小割,則它就是一個必須邊。
對於邊 \(u\rightarrow v\),它作為可行邊存在的條件是:首先,它必須滿流;此外,割掉它之后必須得起效果,因此殘量網絡上從 \(u\) 不能到達 \(v\)。這道題實際上就是要求我們按照 \(C\) 的順序逐個取出可行邊,並在殘量網絡上固定修改。前者我們已經知道如何解決了,而后者則是還原之后重新跑一邊最大流就可以完成的任務。
必須邊:對於一條邊 \(e\),如果對於所有的最小割,\(e\) 都作為割邊存在,則它是一條必須邊。
對於 \(u\rightarrow v\),它作為必須邊存在的條件是:首先滿流;其次,我們得保證如果不割掉它,\(s\) 就必然可以到 \(t\),反映到圖上,這就意味着殘量網絡上從 \(s\) 可以到達 \(u\),而從 \(v\) 可以到達 \(t\)。
此外還有隨便構造割的問題——設 \(V_s\) 為殘量網絡上 \(s\) 可以到達的點的集合,我們直接構造為 \([V_s,V\setminus V_s]\) 即可。
小結:網絡流上關於割的構造問題還是相當值得注意一下的。
「CmdOI2019」星際kfc籃球賽
題目鏈接:LG。
這題總給人一種縫合怪的感覺。不僅縫合,還很怪
前半部分需要建出完全圖上的最小 xor 生成樹......的 Kruskal 重構樹。求最小 xor 生成樹是經典問題,直接在 01 Trie 上面貪心即可,此外事實上可以直接在求最小生成樹的過程中將重構樹建出來。
特別注意:當 01 Trie 有兩個兒子的時候,我們在兩個兒子的連通塊之間,只會連一條邊。
后半部分比較神奇。如果直接做比較麻煩,因為我們相當於考慮 3 個區間、6 個偏序。但是,注意到這里的區間限制是可以差分的,因此可以將前面兩棵樹的區間限制轉化成前綴限制,而后跑莫隊,用分塊或 BIT 維護第三棵樹即可。
特別注意:莫隊復雜度為 \(O(n\sqrt q)\),理論上最優塊長應該是 \(O(\sqrt{\frac{n^2}q})\)。
「ARC076C」Connected?
題目鏈接:AT。
容易發現,只有兩個端點都在邊界上數的才會決定答案。事實上我們只需要檢查這些數直接連成線段之后交不交就可以了。
注意到,矩陣的邊界對應的其實是一維的情況。我們考慮把邊界直接展開,這樣的話原先的線段拍到直線上,就是一個匹配關系。我們只需要保證這樣的匹配關系不交(或者,形成類似“括號匹配”的結構)即可,排序之后檢查就可以了。
話說我直接寫一個暴力判線段交不交的程序為啥 WA 了?
「ARC076D」Exhausted?
題目鏈接:AT。
特殊圖的二分圖匹配,Hall 定理是一個很好的切入角度。
最開始想的是,存在完全匹配的某個左部集是否滿足擬陣性質?證不來,但是寫了一下,發現會 WA 幾個點。
事實上,由 Hall 定理可以得到一個很重要的推論:設 \(n(S)\) 為點集 \(S\) 的鄰接點集,則二分圖的最大匹配為:
如果將這個定理運用到本題上,我們可以將 \(n(S)\) 取補集,這樣原先的並集就會變成補集的交集。計算一下,最終只需要最大化:
這個容易放到區間上,再使用線段樹維護。
小結:主要是想記錄一下這種 Hall 定理的用法,在特殊二分圖最大匹配中應該會比較有效。此外,還應該了解一下 Hall 的 t-條件,這是一個充分的條件(原 Hall 定理是充要的)。
「CF672E」Orchestra
主要的難點在於:首先要想到“卡上下界”然后枚舉的 \(O(r^2c)\) 的思路,其次還得注意到,這個東西會因為 \(k\) 很小而可以優化。
想到了這個方向之后,再去考慮如何動態維護,以及倒序刪除之類的,都不是很困難。
小結:最開始一定不能把思路限制死了,多留幾個出路,方便之后能有選擇。如果要找,則最好從暴力入手,並且要提供一定的時間給可能的方向,而不能直接叉掉。
「ARC016D」軍艦ゲーム
題目鏈接:LG。
顯然可以寫出一個 DP:設 \(f_{u,h}\) 表示從 \(u\) 出發,當前血量為 \(h\) 時的期望步數。
轉移比較神奇:
不妨認為 \(f_{n,x}=0,x>0\) 和 \(f_{u,x}=+\infty,1\le u<n,x<0\)。
這個轉移奇妙的地方就在於,它幾乎沒有出現了環——除了所有狀態都有可能聯系到 \(f_{1,H}\) 以外。為了消除后效性,我們嘗試將 \(f_{1,H}\) 作為變量,比如叫 \(x\),並枚舉它,然后再檢查。
更進一步地,嘗試加速這個過程。一個想法是,二分 \(f_{1,H}\le A\),並以 \(f_{1,H}=A\) 來計算,檢查最終結果是否 \(\le A\)。這個做法是對的,因為我們注意到最終 \(f_{1,H}\) 可以被表示為若干條關於 \(x\) 的直線取 \(\min\)——眾所周知,會構成一個凸包。而這個凸包斜率總 \(\le 1\),因此和 \(y=x\) 只會有一個交點,我們相當於在嘗試二分這個交點。
小結:
個人感覺,將 \(f_{1,H}\) 看作變量和觀察 \(f_{1,H}\) 為凸包結構並進行二分,這兩點比較好。
「PA2014」Druzyny
題目鏈接:LG。
啟發式分治優化 DP。被卡住的地方是——\(c\) 和 \(d\) 的關系並不是等價的。
如果我們把 \(c\) 拿來分治,則 \(d\) 的后綴最小值和區間長度是異調的,這樣只考慮 \(d\) 時,每個右端點/左端點的可用左端點/右端點是單調的。但是,如果先入為主地將 \(d\) 拿來分治,則 \(c\) 沒有這樣好的性質。
雖然兩者在分治過程看是等價的,但是在分治之外就不是。
「CF822E」Liar
題目鏈接:LG。
我是 sb,我光知道按着 \(t\) 來 DP,不知道可以按着 \(s\) 來 DP。如果把 \(s\) 的匹配狀態壓到 DP 狀態里,則 \(t\) 必須連續匹配,而 \(s\) 的不連續可以用前綴轉移來優化掉。這樣再配合后綴數組就很簡潔了。
小結:
總得來說也是和上一節一樣的,要明智地回退。
但是終究很難落實,什么時候該回退,什么時候不該,說不清楚。
與其亂撞,倒不如一開始就利用好其中匹配的性質,同時利用好 DP 轉移的簡便性。
「LGP5824」十二重計數法
題目鏈接:LG。
最后一個整數拆分,限制盒子數,從那個原始的 \(O(n^2)\) 入手就可以了。
誤以為這個東西沒法優化,居然試都不試一下。這種錯誤應該盡量減少!
小結:
避免先入為主的想法,如果遇到困難時一定要留下“回溯”的選項!!!
「LOJ6243」關燈問題
題目鏈接:LOJ。
這道題像是腦筋急轉彎啊。純高消的話時間不會低於 \(O(\frac{n^4}{\omega})\),還需要 band matrix 的 trick。
顯然,我們只能考慮列幾個主元出來。但是,如果我們單純地提一行一列出來,或者提一行出來列主元,則沒有辦法消掉環。
怎么辦呢?觀察一個方程的形式:
稍微移一下項,發現如果推出一個新的變量,需要至少兩列/兩行的變量。所以把前兩列/前兩行都列入主元就好了!
小結:列主元本質是希望通過方程生成遞推關系,所以應當從方程入手,確定哪些應該變成主元。
「UVA11754」Code Feat
題目鏈接:LG。
當 \(\prod k\) 比較小的時候,直接枚舉所有解就可以了。
而當 \(\prod k\) 比較大的時候,根據題解的說法,可以枚舉一組限制並生成所有可能的解,再拿去判斷是否滿足其他解。此時,可以選取 \(\frac{k}{X}\) 最小的來枚舉,但是復雜度仍然未知。
小結:本來想記錄一下枚舉部分限制的解,再將這部分解拿來檢驗的這種思路;不過看來也遺留下來了復雜度的問題 😅。
POI 兩道字符串
題目鏈接:「POI2012」PRE-Prefixuffix,
顯然我們需要枚舉一個 Border。問題在於,如何盡快求出去掉一個 Border 之后,剩下的串的 Border?
不妨設 \(f_{k}\) 為,刪掉前 \(k\) 個字符后,剩余字符串的 Border 的最大值。從 \(f_{k+1}\) 到 \(f_{k}\),加入字符似乎不好處理,那么反過來,考慮刪除字符,此時就容易發現有 \(f_{k+1}\ge f_k-2\),也即是 \(f_{k}\le f_{k+1}+2\)。這樣就給 \(f_k\) 定了一個上界,我們再按照刪除的順序做即可。
題目鏈接:「POI2005」SZA-Template。
寫了一個 Border 鏈 + 線段樹的 zz 做法,不想說了。
設 \(f_k\) 表示前綴 \([:k]\) 的答案,則會發現性質:\(f_k\) 要么是 \(k\),要么是 \(f_{\operatorname{nxt}_k}\)。這其實就是在 Border 中隱含的遞推關系,而直接維護 Border 鏈就是將這一層遞推關系展開后的愚蠢做法。
檢查是否可以取到 \(f_{\operatorname{nxt}_k}\) 是容易的,這里不再贅述。
小結:在掃描過程中,對於 Border 的處理其實很像是在做 DP,我們要么轉移到一個新狀態,要么轉移到一個可以由 Border 計算好的狀態。在其他后綴結構中也有這個性質,所以不要每次都想着顯式地展開后綴鏈處理!
「CF453D」Little Pony and Elements of Harmony
題目鏈接:LG。
取模才是最復雜的部分 😅。
在 IFWT 的時候,我們可以把所有的 \(\frac 1 2\) 全部提出來,也就是最終只需要整體除掉一個 \(2^m\)。由於 \(\bmod p\) 意義下不可能這樣隨便除,我們可以考慮擴到 \(p\) 的一個倍數的模下面運算,保證在那個范圍之中可以除掉這個 \(2^m\),再還原到 \(p\) 的模即可。
有了這個思路,就不難想到擴到 \(2^m\times p\) 了。
「WC2018」州區划分
題目鏈接:LG。
這道題,最后雖然看似需要“分治卷積”,但你思考一下,既然子集卷積已經需要記錄集合大小了,那么直接按照集合大小來從小到大卷積,就已經足以保證轉移的單向性了!
「Gym102956A」Belarusian State University
題目鏈接:Gym。
這道題告訴我們:
-
所謂集合卷積,實際上就是多元卷積,這樣就隱含了獨立性。
-
嘗試通過已有的結果,進行一定的變換之后解決問題,這樣的思路總是值得考慮的。
尤其是像這一道題目,既然只有 16 種真值表,那么嘗試直接轉化到 3 種基礎的卷積也是合情合理的。
「LG P5349」冪
題目鏈接:LG。
直接轉下降冪多項式是愚蠢的,根本不需要思考的好伐?
嘗試使用一些基本的數學方法來解決這個問題。本質上只需要求出:
套用錯位相減法,可以得到最終的結果為:
然后分治 FFT。
小結:回歸基礎方法。一些技巧固然可貴,但是根本的路徑是不能被隨便遺棄的......