雜題選做Ⅳ


NOIp 前夜了,可我還是發現自己有一車 blog 沒補,所以只好開一個新坑/wul

前傳:

76. CF1539E Game with Cards

考慮設 \(dp_{i,0/1}\) 表示目前已經進行了前 \(i\) 次操作,第 \(i\) 次操作替換了左手/右手是否可行,以 \(dp_{i,0}\) 為例,轉移就枚舉上一次使用右手是拿一次操作,不妨稱之為 \(j\),那么有轉移 \(dp_{i,0}\leftarrow dp_{j,1}\land[a_{l,j+1}\le k_{j+1}\le b_{l,j+1}]\land[a_{l,j+2}\le k_{j+2}\le b_{l,j+2}]\land\cdots\land[a_{l,i-1}\le k_{i-1}\le b_{l,i-1}]\land[a_{r,j+1}\le k_j\le b_{r,j+1}]\land\cdots\land[a_{r,i-1}\le k_j\le b_{r,i-1}]\)。直接做是三方的,顯然不可取,因此考慮預處理一些東西。

我們預處理出 \(nxt_{i,0}\) 表示最大的 \(r\),滿足 \(\forall j\in[i+1,r]\) 都有 \(a_{l,j}\le k_i\le b_{l,j}\),同理設 \(nxt_{i,1}\) 表示最大的 \(r\),滿足 \(\forall j\in[i+1,r]\) 都有 \(a_{r,j}\le k_i\le b_{r,j}\)

我們再設 \(pre_{i,0}\)​ 表示最小的 \(l\)​,滿足 \(\forall j\in[l,i]\)​ 都有 \(a_{l,j}\le k_j\le b_{l,j}\)​,以及 \(pre_{i,1}\)​ 表示最小的 \(l\)​,滿足 \(\forall j\in[l,i]\)​ 都有 \(a_{r,j}\le k_j\le b_{r,j}\)

那么 \(dp_{j,1}\) 可以轉移到 \(dp_{i,0}\) 的充要條件是 \(dp_{j,1}=1\),且 \(nxt_{j,1}\ge i,pre_{i,0}\ge j\)。因此我們考慮建兩棵樹狀數組 \(T_0,T_1\),對於一個 \(dp_{i,0}=1\)\(i\),我們就令 \(T_0\)\(nxt_{i,0}\) 的上位置對 \(i\)\(\max\)​,對 \(dp_{i,1}\) 也進行同樣的操作,那么 \(dp_{i,0}=1\),等價於樹狀數組 \(T_1\)\([i,n]\) 的后綴 \(\max\) \(\ge i\)​,\(dp_{i,1}=1\) 的條件也是類似的,這個在樹狀數組查一遍后綴 \(\max\) 即可轉移。

至於輸出路徑,就隨便記錄一個 \(pre_{i,0/1}\) 表示 \(dp_{i,0/1}\) 是從哪兒轉移來的,然后最后不停地跳 pre 即可。

時間復雜度 \(\Theta(n\log n)\)

77. AT2667 [AGC017D] Game on Tree

打 CF GR 時發現 I 題題面里有一道我沒做過的 AGC 就在棄賽以后來做了(

首先先拋結論:考慮 SG 定理,那么每個子樹的 SG 值等於其所有兒子的子樹的 SG 值加 \(1\) 的異或和。

為什么呢?考慮每次刪除一個子樹 \(x\) 內的邊的過程是怎么樣的,我們假設 \(x\)\(t\) 個兒子,那么我們將 \(x\) 復制 \(t\) 邊,然后每個 \(x\) 下面都接上 \(x\) 的一個兒子的子樹。那么顯然這 \(t\) 棵樹可以視作獨立的游戲,直接將它們的 SG 值異或起來就是原游戲的 SG 值。那么又該如何算根節點只有一個兒子的游戲的異或值呢?可以證明,如果根節點只有一個兒子的情況,那么它的 SG 值就等於它唯一的兒子的子樹的 SG 值加 \(1\),這個就考慮,如果我們割掉了 \(x\) 與這個兒子之間的邊,那么只剩下一個節點,SG 值顯然為 \(0\),而如果第一次割掉的邊不是 \(x\) 與其兒子的邊,那么我們歸納一下可以得到剩下部分的 SG 值就等於去掉根節點后剩余部分的 SG 值加一。換句話說,對於割掉 \(x\) 的兒子的子樹內的邊可以得到的 SG 值 \(x\)\(x+1\) 同樣可以被得到,反之對於對於割掉 \(x\) 的兒子的子樹內的邊后不可以得到的 SG 值 \(x(x\ge 0)\)\(x+1\) 同樣不可以得到,這樣 \(x\) 的子樹的 SG 值就顯然等於其兒子的 SG 加一。

78. CF1610I Mashtali vs AtCoder

關於上題中提到的 GLBR 的 I 題,它來了(

首先套用上一題的結論解決 \(k=1\) 的情況:一棵子樹的 SG 值等於其兒子的 SG 值 \(+1\) 的異或和。

對於 \(k>1\) 的情況,有這樣的結論:我們將編號為 \(1,2,3,\cdots,k\) 的點拎出來建一棵虛樹並縮成一個點,不妨令這個點為根節點,然后將所有在縮點后,一個端點在縮成的連通塊,另一個端點不在的邊全部接到根節點上,那么 \(k\) 時的 SG 值,就等於以縮點之后的點為根計算出它們的 SG 值后,根節點的 SG 值,異或上 \(1\sim k\) 的虛樹中的邊數 \(\bmod 2\),只不過在計算根節點的 SG 值時,直接將根節點的兒子的 SG 值異或起來即可,不用 \(+1\)

這里稍微胡半個證明:首先我們稱連接兩個都在虛樹中的邊的點為一類邊,其余的邊為二類邊,那么我們將割掉的邊分為一類邊和二類邊處理,如果我們割掉一條一類邊,那么根據 SG 值的定義,這條邊所在縮點之后根節點的子樹的 SG 值肯定會發生變化,而如果我們割掉一條二類邊,那么二類邊的奇偶性就會變化,因此不論割掉什么邊,游戲的 SG 值總會發生變化。

為什么說是半個證明呢?因為我不太會證為什么一種局面總可以到達 SG 值比它小的局面(

因此對於本題而言,我們可以直接向上面那樣加入一個點時不斷跳 father 並將路上經過的邊標記為二類邊,由於每條邊最多被標記一次,因此總復雜度 \(\Theta(n)\)

79. CF1612F Armor and Weapons

首先關鍵性質:答案不超過 \(\dfrac{\max(n,m)}{\min(n,m)}+40\)

因此不妨假設 \(dp_{i,j}\) 表示目前武力值最高的盾的武力值為 \(i\),進行了 \(j\) 次操作,所能夠得到武力值最大的武器,轉移就分下一次買盾和買武器處理即可。

時間復雜度 \(40n\log n\),瓶頸在於判斷一對 \((i,j)\) 是否在讀入的 \(q\) 組二元組中出現過。

80. CF1338D Nested Rubber Bands

一道看似很無從下手的題。不過仔細分析一下還是挺有跡可循的(

首先碰到這樣的問題我們肯定要考慮什么樣的序列可能符合條件。分析一下能夠得到,一種選擇符合條件,當且僅當對於所有點 \(u\),都不存在三個鄰居 \(x,y,z\),滿足去掉 \(u\) 后三個點所在的連通塊中,都除了 \(x/y/z\) 之外還選擇了其他的點,這是因為假設 \(x\) 所在的連通塊中選擇了 \(a(a\ne x)\)\(y\) 所在的連通塊中選擇了 \(b(b\ne y)\)\(z\) 所在的連通塊中選擇了 \(c(c\ne z)\)。且方便起見假設 \(c\) 包含於 \(b\)\(b\) 包含於 \(a\),那么畫出圖來肯定是張這樣的:

而我們希望 \(u\)\(x,z\) 相交而與 \(b\) 不相交,顯然在上圖中這無法辦到。

直接用這個結論解題貌似有點難以下手,我們不妨對這個結論進行等價轉換。可以發現一種等價的表述:對於每一種合法的方案,必然存在一條路徑 \(u,v\),滿足所有選擇的點到這條路徑距離 \(\le 1\),也就是說題目等價於選擇一條路徑 \(u,v\),並將所有到這條路徑距離 \(\le 1\) 的點提取出來求出它們的最大獨立集。直接做顯然會 TLE,考慮 \(dp\) 的思想,設 \(dp_{i,0/1}\) 表示目前考慮到 \(i\)\(i\) 是鏈的一個端點並且 \(i\) 選了 / 沒被選所能選擇的最大的點數。考慮轉移,假設我們目前 DFS 到點 \(x\),下面要加入 \(x\) 的一個兒子 \(y\),那么有轉移:

\[res \leftarrow \max(res, \max\limits_{i\land j = 0} dp_{x, i} + dp_{y, j}) \]

\[dp_{x, 0} \leftarrow \max(dp_{x, 0}, \max(dp_{y, 0}, dp_{y, 1}) + deg_x - 2) \]

\[dp_{x,1} \leftarrow \max(dp_{x, 1}, dp_{y, 0} + 1) \]

直接轉移即可。時間復雜度線性。

81. AT4518 [AGC032C] Three Circuits

不難發現,一個連通塊是一個題目中所謂的“可以經過重復點的環”,當且僅當它存在歐拉回路,即它連通並且每個點的度都是偶數。

那么我們的任務就可以轉化為,將連通塊的邊集分成三部分 \(A,B,C\),滿足它們都有歐拉回路。一個顯然的必要條件是每個點在原圖中的度都是偶數,否則假設 \(x\) 在原圖中的度是奇數,那么在 \(A,B,C\) 中,至少有一部分滿足 \(x\) 的度是奇數,不合題意。但是每個點的度都是偶數的情況也不一定符合條件,譬如一個環的情況就無法拆成符合條件的三個子圖,因此考慮進一步分類討論:

  • 如果存在一個點 \(x\) 的度 \(\ge 6\),那么我們感性地理解一下,每次選擇這個點的兩條出邊,然后順着找出經過這兩條出邊的一個環,然后將這個環從這張圖中刪去,如果刪去這個環之后圖被分成了兩個連通塊,那么我們就將不包含 \(x\) 的部分與之前拆出來的那個環歸到同一個邊集中。如此操作兩次,連帶剩余的部分,剛好三個回路。

  • 如果所有點度都 \(\le 2\),那么原圖是一個環,顯然無法完成任務。

  • 如果度數最大的點的度數恰好等於 \(4\),這部分有點繁瑣,我們進一步分類討論:

    • 如果度數為 \(4\) 的點只有一個,那么任務也沒法完成,輸出 No

    • 如果度數為 \(4\) 的點的個數 \(\ge 3\),那么畫個圖感性理解一下總是有解的,直接輸出 Yes 即可。

    • 如果度數為 \(4\) 的點的個數恰好等於 \(2\),那么再手玩一下可以發現這種情況的圖可以被分為兩大陣營,一類如下圖左邊所示,這種情況下原圖無法拆成三個環;一類如下圖右邊所示,這種情況下原圖可以被拆成三個環。那么我們如何區分這兩類呢?我們找出原圖中兩個四度點 \(A,B\),稍微分析一下可以發現,一張圖屬於右邊那個陣營,當且僅當 \(A\) 的所有鄰居 \(x\)​ 中,滿足 \(x\) 能夠不經過 \(A\) 到達 \(B\) 的點數 \(\le 2\)​,這個直接枚舉一下然后 DFS 一遍即可。

時間復雜度線性。

82. P5362 [SDOI2019]連續子序列

首先思考什么樣的序列 \(S\) 能夠成為 T.M 序列的子序列。我們發現這個 T.M. 序列的定義有點像一個二叉樹的結構,具體來說 T.M 序列可以通過如下方式得到:首先寫上一個 \(0\),然后建立一棵以 \(1\) 節點為根無限延伸的滿二叉樹,\(1\) 號節點的權值為 \(1\),對於每個節點,如果它的權值是 \(0\),那么它的左兒子權值為 \(0\),右兒子權值為 \(1\),否則它的左兒子權值為 \(1\),右兒子權值為 \(0\)。然后將每一層的數字按順序寫下來即可得到完整的 T.M. 序列。

不難發現上面的過程可以用“長”的過程來類比,受到上面的思想的啟發,我們不妨也來考慮 \(S\) 是從什么序列 \(T\) 長出來的,對於一個序列 \(S\),分情況討論:

  • 如果 \(|S|\) 為奇數,那么有兩種可能的長法:
    • 一是將 \(S\) 中字符按 \(S_{1},S_{2}\) 配對,\(S_3,S_4\) 配對,\(\cdots\)\(S_{|S|-2},S_{|S|-1}\) 配對,如果配對的兩個字符是 \(01\) 則在 \(T\) 末尾插入一個 \(0\),否則如果是 \(10\) 則插入一個 \(1\),否則則說明不可能是通過這種方式長出來的,最后落單的元素 \(S_{|S|}\) 就直接加入 \(T\) 末尾即可。
    • 另一種是將 \(S\)​ 中字符按 \(S_{2},S_{3}\)​ 配對,\(S_4,S_5\)​ 配對,\(\cdots\)​,\(S_{|S|-1},S_{|S|}\)​ 配對,然后按照上一種情況的方式往 \(T\) 里面插入元素。這樣開頭會有一個落單的元素,在 \(T\) 的開頭預先插入一個 \(S_1\oplus 1\)​ 即可。
  • 如果 \(|S|\) 為偶數,那么也有兩種可能的長法:
    • 一是將 \(S\)​ 中字符按 \(S_{1},S_{2}\)​ 配對,\(S_3,S_4\)​ 配對,\(\cdots\)​,\(S_{|S|-1},S_{|S|}\)​ 配對的方式插入字符。
    • 還有一種方式是將 \(S\) 中字符按 \(S_2,S_3\) 配對,\(S_4,S_5\) 配對,\(\cdots\)\(S_{|S|-2},S_{|S|-1}\)​ 配對。這樣 \(S_1\)\(S_{|S|}\) 均會落單,這可以通過把 \(S_1\oplus 1\) 插到 \(T\) 的開頭,\(S_{|S|}\) 插到 \(T\) 的結尾。

可以證明,如果 \(|S|>3\),那么對於任意一個是 T.M. 序列的子序列,總存在唯一的拆分方式,因為對於 T.M 序列中任意一個長度 \(\ge 4\) 的連續段,總存在相鄰且相同的字符。這就導致恰好一種拆分方式不合法,因此對於 \(|S|\le 3\) 特判一下,否則如果 \(T\) 符合要求,那么 \(S\) 也符合要求,遞歸一下即可,時間復雜度 \(\Theta(\sum\limits_{k}\lfloor\dfrac{|S|}{2^k}\rfloor)=\Theta(|S|)\)。即我們實現了在 \(\Theta(|S|)\) 的時間內判定一個字符串是否是 T.M. 序列的子序列。

接下來考慮如何計算答案。我們設 \(f(S,k)\) 表示往 \(S\) 后面添 \(k\)​ 個字符后能夠得到多少 T.M. 序列的子序列,如果 \(|S|+k\le 3\),那么特判一下即可得到,否則根據上面的結論,我們枚舉得到的字符串是由哪種拆分得到的,這樣我們可以得到 \(S\) 對應的序列 \(T\)。進而得到新的 \(k\),繼續遞歸計算即可,時間復雜度 \(T(|S|+\log_2(k))\)

83. CF360E Levko and Game

思維題殺我/dk

不難發現對於每一條權值自定的邊,如果它的權值既不是 \(l_i\) 也不是 \(r_i\),那么我們將其調整為 \(l_i\)\(r_i\) 肯定不會影響答案,因為如果它被先手經過沒被后手經過,那么我們將它調整為 \(l_i\) 肯定更優;如果它被后手經過而沒被先手經過,那么我們將它調整為 \(r_i\) 肯定最優。而如果它既被先手經過也沒被后手經過,那不論將其調整為 \(l_i\) 還是 \(r_i\),得到的新圖中這條邊都要么被先手和后手同時經過,要么同時不經過。

因此我們考慮這樣的算法:我們先將所有邊的權值設為 \(r_i\),但是這樣會導致某些被先手經過但沒被后手經過的邊的權值過大,這樣就導致方案不優,因此我們需要調整。我們設 \(s_1\)\(x\) 的距離為 \(d1_x\)\(s_2\)\(x\) 的距離為 \(d2_x\),那么對於一條權值自定的邊 \((u,v)\),如果 \(d1_u<d2_u\),那么我們就將這條邊的權值調整為 \(l_i\) 並重新 dijkstra 一遍算出 \(d1,d2\)。如果最終 \(d1_f<d2_f\),那么說明先手贏了,直接輸出每條邊的邊權,否則我們嘗試讓先手與后手打成平手,即還是先假設所有邊權值都是 \(r_i\),然后每次還是求出 \(s_1,s_2\) 到所有點的最短路並枚舉所有權值自定的邊 \((u,v)\),如果 \(d1_u\le d2_u\),那么我們就將這條邊權值調整為 \(l_i\),最后檢查是否有 \(d1_f\le d2_f\),如果成立則輸出 DRAW,否則輸出 LOSE

為什么這樣做是正確的?以前一部分,也就是判斷答案是否可能為 WIN 的一半為例,對於每條權值自定的邊 \((u,v)\),如果 \(d1_u<d2_u\),那么將這條邊權值調整為 \(l_i\) 之后,仍然有 \(d1_u<d2_u\),也就是說在最終的局面中,所有存在一種定邊權的方式,滿足 \(d1_u<d2_u\) 的權值自定邊 \((u,v)\) 的權值都被調至 \(l_i\),而其他權值自定邊在任何局面下都有 \(d1_u\ge d2_u\),不會對答案產生任何正面影響,因此最終這個局面肯定是最優的。

時間復雜度 \(mk\log m\)​。

84. P3330 [ZJOI2011]看電影

一道出現了 \(10^9+7\) 次的題目(大霧

考慮在 \(k\) 位置后面加入一個 \(k + 1\) 位置並將整個模型變成一個環,那么一種分配方式符合條件當且僅當 \(k+1\) 沒有被占。

如果我們每次可以在 \(k+1\) 位置放人,那么理論上來說每個點被占的概率都是相同的,因此滿足 \(k+1\) 沒有被占的方案數就是 \((k+1)^n·\dfrac{k+1-n}{k+1}=(k+1-n)(k+1)^{n-1}\),答案就是 \(\dfrac{(k+1-n)(k+1)^{n-1}}{k^n}\)

比較煩的一點是要寫高精。

85. P5292 [HNOI2019]校園旅行

首先看到這道題我們可以很自然地想到一個 \(m^2\) 的做法:設 \(can_{i,j}\) 表示 \(i,j\) 之間是否存在符合條件的路徑,然后類似 BFS 的思路,擴展到一個 \(can_{i,j}\) 時就遍歷一遍 \(i\) 的所有鄰居 \(x\)\(j\) 的所有鄰居 \(y\),如果 \(s_x=s_y\)\(is_{x,y}=0\) 就令 \(is_{x,y}=1\) 並將 \((x,y)\) 這個二元組放入隊列里繼續 BFS。顯然每對邊組成的二元組最多被遍歷一次,總復雜度就是 \(\Theta(m^2)\)

這樣顯然過不了,考慮優化。注意到這題 \(m\) 級別比 \(n\) 高很多,對於有這樣的性質題,一種思路是仔細分析一樣是否所有邊都是有用的,如果不是那就踢掉那些無用的邊,讓邊數的級別降得和點數一樣。此題就是這種思路,我們將邊分為三類:兩個端點都是 \(0\)、兩個端點都是 \(1\)、兩個端點一個是 \(0\) 一個是 \(1\)。我們將這三類邊拎出來各建一張圖,對於每張圖,我們考察每個連通塊,找出它的一個生成樹並將其加入原圖,這樣邊數就降到了 \(\Theta(n)\) 級別。

但這樣做其實是錯誤的,因為對於一個全由 \(0\) 邊組成的連通塊,如果我們只找出它的生成樹,那就默認所有環的大小都是偶數(因為樹是一個二分圖),但實則不一定,因此我們需要對由全 \(0\) 邊和全 \(1\) 邊組成的圖的每個連通塊,跑一遍二分圖染色檢驗其是否是二分圖,如果不是那就在這個連通塊對應的生成樹上加個自環,不難發現這樣原圖就與新圖等價了。然后跑上面的暴力即可。

時間復雜度 \(n^2+m\alpha(n)\)

86. CF1609F Interesting Sections

講個笑話,vp 的時候想交這道題的時候 CF 崩掉了,卡了 1h 直到 vp 結束后 3min 才好,好在最后我的第一發提交因為常數太大 T 了,否則就虧大了……

考慮枚舉最大值和最小值的 popcount,那么問題等價於,給定一個序列 \(a_i\),其中有一些位置是關鍵位置,要求有多少個區間,滿足其最大值和最小值都是關鍵位置。

碰到數區間問題無非兩個套路:枚舉右(左)端點或分治,這次咱們采取前者,我們掃描線式枚舉右端點 \(r\),掃描到 \(r\) 時,我們記 \(f_l\) 表示 \([l,r]\) 中最大值是否關鍵位置 \(+\) \([l,r]\) 中最小值是否是關鍵位置,那么顯然 \(f_l\) 的變化可以通過單調棧求出,那么對於一個右端點 \(r\) 和一個 popcount \(v\),其對答案的貢獻就是 \(f_l=2\)\(l\) 的個數。注意到 \(f_l\) 的上界就是 \(2\),因此這個可以通過區間最大值及其出現次數的線段樹維護。

算下復雜度,乍一看這個做法復雜度是 2log 的,但實則不是。因為我們單調棧時修改次數均攤下來是 \(\mathcal O(n)\) 的,而查詢我們只用用到根節點存儲的值,因此雖然查詢次數可以達到 \(n\log v\),單次查詢是 \(\mathcal O(1)\) 的這一事實導致復雜度也不算太高,這樣總復雜度就是 \(n(\log v+\log n)\),可以通過。

注意常數問題!!!!!1111

87. CF1584G Eligible Segments

由於這篇博客里混入了太多奇怪的東西,2021.11.30 決定將博客名改為“雜題選做”

首先,一個點 \(P_k\) 到線段 \(P_iP_j\) 的最小距離 \(\le R\) 等價於 \(P_k\) 到射線 \(\vec{P_iP_j}\) 的距離 \(\le R\)\(P_k\) 到射線 \(\vec{P_jP_i}\) 的距離也 \(\le R\)。那么我們就設 \(is_{i,j}\) 表示是否對於所有 \(k\) 都有 \(P_k\)\(\vec{P_iP_j}\) 的距離 \(\le R\),那么答案就是滿足 \(i<j,is_{i,j}=is_{j,i}=1\) 的二元組 \((i,j)\) 的個數。

考慮如何求 \(is_{i,j}\),我們枚舉 \(i\),對於每個 \(k\),我們求出 \(P_i\) 到以 \(P_k\) 為圓心 \(R\) 為半徑的圓的兩條射線的輻角 \(\theta_1,\theta_2\),那么 \(is_{i,j}=1\) 當且僅當 \(\vec{P_iP_j}\) 的輻角在所有 \([\theta_1,\theta_2]\) 的交中,簡單判斷一下即可。

時間復雜度 \(n^2\)

88. CF633G Yash And Trees

這就是我嗎?套路題和思維題都不會做嗎?/fn/fn/fn

考慮將樹拍平變成一個序列,然后以 DFS 序為下標建立一棵線段樹,線段樹上每一個節點開一個 bitset 維護這個區間內每種數是否出現過。那么每次進行子樹加時,就在對應的區間上進行區間加,這樣對應在 bitset 上的變化就是 v = (v << x) | (v >> (m - x)),其中 \(x\) 為增加的量,直接打個標記即可。查詢就把對應區間內的 bitset 進行一遍 or 即可。

時間復雜度 \(\dfrac{nm\log n}{\omega}\)

話說這場的 H 我的題解好像還沒有補呢,都 8 個月了,估計這輩子都不會補了(

89. CF1019D Large Triangle

首先狠狠吐槽一句,tm 這題明明三角形格點橫縱坐標都是整數,因此三角形面積要么是 .0 要么是 .5 才對啊,為什么偏偏 checker 會說我輸出的三角形面積等於 \(xxxx.1\)?我實在是不能理解了,難道選手做題是為了適應 checker 的嗎?/fn/fn/fn

一開始想着用向量叉積搞,后來事實證明這種東西對於此題而言沒前途(

考慮枚舉三角形的一條邊 \(AB\),我們考慮將所有點按該點到直線 \(AB\) 的有向距離從小到大排序,如果我們能實現這樣的操作,那么我們顯然向左向右各二分一下即可檢驗是否存在面積等於 \(S\) 的三角形。

於是問題轉化為,我們如何動態地對於一條線段,維護所有點到直線 \(AB\) 的有向距離排好序后的結果。可以注意到,一個點到直線 \(AB\) 的有向距離,可以轉化為,過這個點做 \(AB\) 的平行線后,直線與 \(y\) 軸交點的縱坐標。那么我們考慮一個斜率 \(k\)\(-\infty\) 變到 \(\infty\) 的過程,並設想我們過每個點都做了一條斜率為 \(k\) 的直線,這些直線與 \(y\) 軸各會產生一個交點,我們要比較這些交點的縱坐標的大小。不難發現,對於一個點對 \((i,j)\),滿足 \(x_i\ne x_j\) 且當 \(k\) 趨近於 \(-\infty\) 時,\(i\) 的截距 \(<j\) 的截距,那么必定存在一個斷點 \(k_0\),滿足 \(k<k_0\)\(i\) 的截距 \(<j\) 的截距,對於 \(k>k_0\) 的情況則反過來,那么我們考慮將這個過程用個 vector 存下來並將所有這樣的事件按 \(k_0\) 排序,再將所有線段按 \(AB\) 的斜率從小到大排序,然后掃描線段時直接在存儲的事件的數組里 two pointers 即可,每次遇到一個“\(i\) 的截距反超了 \(j\) 的截距”的事件,我們就交換 \(i,j\) 的排名。顯然此時 \(i,j\) 的排名是相鄰的,故我們不用進行多余的調整。這樣我們就動態地維護了所有點到 \(AB\) 距離的有向距離的大小。

時間復雜度 \(n^2\log n\)

90. AT4519 [AGC032D] Rotation Sort

首先考慮一個非常顯然的性質:每個數最多被移動一次,否則我們肯定第一次就會將其移動到它最終的位置。發現這個性質之后,我們就可以很自然地將所有數分為兩類:被移動過和沒被移動過。我們考慮固定住那些沒有被移動過的位置,那么對於兩個相鄰的沒有被移動過的位置 \(l,r\) 之間的位置 \(i\),有兩種選擇:如果 \(a_i>a_r\),那么只能向右移動,否則由於我們欽定它必須移動,那么我們不妨假設剩余位置必須向左移動。這樣我們就可以設計出一個 DP:\(dp_i\) 表示考慮了 \(a_1\sim a_i\),且 \(a_i\) 沒有被移動所需花費的最小代價,\(\Theta(n)\) 轉移即可,總復雜度 \(n^2\)。可以通過線段樹優化到 \(n\log n\),但對於此題來說沒有必要。

91. P4798 [CEOI2015 Day1]卡爾文球錦標賽

一道非常基礎的題,就當剛剛肝了道毒瘤題之后調節一下心情吧(

首先考慮什么樣的序列 \(a\) 符合條件。顯然 \(a\) 中出現過的數必須是一段從 \(1\) 開始的連續的前綴 \(1,2,3,\cdots,x\) 對吧,並且如果我們把這些數第一次出現的位置拎出來,這些首次出現的位置肯定是單調遞增的。容易證明這是充要條件。

發現這個性質之后我們可以很自然地設計出一個類似於數位 DP 的東西:\(dp_{i,j,0/1}\) 表示考慮了前 \(i\) 個位置,目前出現過的最大的數為 \(j\)​,目前沒有 / 有達到上界的方案數,分情況轉移即可。直接開數組會 MLE,滾動數組優化一下即可。

時間復雜度 \(n^2\)

講個笑話,這個模數貌似不是質數,雖然它長得一臉質數的樣子(

92. AT2672 [AGC018C] Coins

首先假設所有人都選了金幣,令 \(p_i=B_i-A_i,q_i=C_i-A_i\),那么題目等價於選擇 \(y\)\(p_i\)\(z\)\(q_i\),滿足它們下標集合交集為空,且選出的這 \(y\)\(p_i\)\(z\)\(q_i\) 的和盡可能大。

考慮反悔貪心,我們先貪心地選出 \(p_i\) 最大的 \(y\) 個數和 \(q_i\) 最大的 \(z\)​ 個數,但是這樣不一定滿足“交集非空”的條件,我們假設此時交集大小為 \(cnt\),那么我們考慮執行 \(cnt\) 次操作,每次操作進行一些微調使交集大小減一,不難發現微調的方式無非以下幾種:

  • 選擇一個 \(p_i,q_i\)​ 都選擇的下標 \(i\)​,和一個 \(p_j,q_j\)​ 都沒選擇的下標 \(j\)​,去掉 \(p_i\)​ 選上 \(p_j\)
  • 選擇一個 \(p_i,q_i\)​​ 都選擇的下標 \(i\)​​,和一個 \(p_j,q_j\)​​ 都沒選擇的下標 \(j\)​​,去掉 \(q_i\)​​ 選上 \(q_j\)​​
  • 選擇一個 \(p_i,q_i\)​ 都選擇的下標 \(i\)​,一個選了 \(p_j\)​ 沒選 \(q_j\)​ 的下標 \(j\)​,還有一個 \(p_k,q_k\)​ 都沒選擇的下標 \(k\)​,去掉 \(p_i\)​,把 \(p_j\)​ 改為 \(q_j\)​,並選上 \(q_k\)
  • 選擇一個 \(p_i,q_i\)​​ 都選擇的下標 \(i\)​​,一個選了 \(q_j\)​​ 沒選 \(p_j\)​​ 的下標 \(j\)​​,還有一個 \(p_k,q_k\)​​ 都沒選擇的下標 \(k\)​​,去掉 \(q_i\)​​,把 \(q_j\)​​ 改為 \(p_j\)​​,並選上 \(p_k\)​​

用六個堆維護即可,即維護:

  • \(Q_1\)​ 裝有所有 \(p_i,q_i\)​ 都選的 \(i\)​ 的 \(-p_i\)
  • \(Q_2\) 裝有所有 \(p_i,q_i\) 都選的 \(i\)\(-q_i\)
  • \(Q_3\)​ 裝有所有 \(p_i,q_i\)​ 都沒選的 \(i\)​ 的 \(p_i\)
  • \(Q_4\)​ 裝有所有 \(p_i,q_i\)​ 都沒選的 \(i\)​ 的 \(q_i\)
  • \(Q_5\)​ 裝有所有選了 \(p_i\)​ 沒選 \(q_i\)​ 的 \(i\)​ 的 \(q_i-p_i\)
  • \(Q_6\) 裝有所有選了 \(q_i\) 沒選 \(p_i\)\(i\)\(p_i-q_i\)

時間復雜度 \(n\log n\)

93. Codeforces Gym 103409 H Popcount Words

首先看到多串匹配相關問題,果斷建出 \(q\) 個模式串的 AC 自動機。

如果我們定義 \(W_{i,j}\) 表示 \(0\sim 2^i-1\) 中所有數的 popcount \(\bmod 2 \oplus j\) 接在一起的結果,其中 \(i\in[0,\lceil\log_2(V)\rceil],j\in[0,1]\)。那么顯然所有 \(w(l,r)\) 都可以像線段樹區間查詢那樣拆成不超過 \(2\lceil\log_2(V)\rceil\)\(W_{i,j}\) 拼在一起的結果。因此我們可以將整個文本串看作 \(\mathcal O(n\log V)\)\(W_{i,j}\) 接在一起的結果。

那么我們如何統計 fail 樹上每個節點被經過了多少次呢?首先考慮倍增,設 \(to_{i,j,k}\) 表示目前在 fail 樹上節點 \(i\),往下讀進去一個 \(W_{j,k}\) 后會走到 fail 樹上哪個節點。我們再設 \(cnt_{i,j,k}\) 表示有多少次在 \(i\) 處向下接 \(W_{j,k}\) 的機遇,那么我們先按照倍增的套路預處理出 \(to_{i,j,k}\),然后按照順序依次讀進去全部 \(\mathcal O(n\log V)\)\(W_{i,j}\),最后再按照 \(j\) 遞減的順序更新 \(cnt_{i,j,k}\),即用 \(cnt_{i,j,k}\) 去更新 \(cnt_{i,j-1,k}\)\(cnt_{to_{i,j-1,k},j-1,k\oplus 1}\) 即可。

時間復雜度 \((n+\sum|s|)·\log V\)​。

94. CF1418F Equal Product

首先思考一下什么樣的 \((x_1,x_2,y_1,y_2)\) 符合條件,這里有一條大概用直覺比較容易發現的性質是,對於符合條件的 \((x_1,x_2,y_1,y_2)\),必然存在整數 \(a,b\),使得 \(x_2=\dfrac{x_1}{a}·b\)\(y_2=\dfrac{y_1}{b}·a\)\(\dfrac{x_1}{a},\dfrac{y_1}{b}\) 均為整數。

證明:考慮設 \(d=\gcd(x_1,x_2)\),然后令 \(a=\dfrac{x_1}{d},b=\dfrac{x_2}{d}\)(說白了就是設 \(\dfrac{b}{a}\) 表示 \(\dfrac{x_2}{x_1}\) 約分以后的結果),那么顯然 \(\dfrac{x_1}{a}=d\) 為整數,而 \(\dfrac{y_1}{b}·x_1=\dfrac{x_2}{b}·y_2=d·y_2\) 為整數,又根據 \(\gcd(a,b)=1\) 可知 \((x_1,b)=1\),因此必然有 \(b\mid y_1\),證畢。

因此我們考慮枚舉 \(x_1\) 時,順帶枚舉符合條件的四元組所對應的 \(a\),那么思考一下什么樣的二元組 \((y_1,b)\) 會符合條件,歸納一下就是下面三條:

  • \(\lceil\dfrac{L}{x_1}\rceil\le y_1\le\min(\lfloor\dfrac{R}{x_1}\rfloor,m)\)
  • \(\dfrac{x_1}{a}·b\le n\)
  • \(a<b\)

我們考慮正序枚舉 \(x_1\),那么第一條中 \(y_1\) 的范圍的左右端點都是不升的,這樣我們可以通過 two pointers 將所有符合條件的二元組 \((b,y_1)\) 扔進一個 set 中,對於后兩條限制,顯然在符合第三條限制的前提下,\(b\) 最小的那個最有可能符合條件二,因此我們直接在 setlower_bound 檢驗即可。

算下復雜度,set 有個 log,而我們 \(x,a\) 的總枚舉量是調和級數級別的,也就是 \(n\ln n\),因此總復雜度 \(n\ln n\log n\),可以通過。

95. CF1519E Off by One

由於每個點必須要移動,因此我們考慮對於每個點 \(i\),求出其向上和向右移動后得到的兩個點 \(P_i,Q_i\),然后將所有出現過的斜率看作一個點並在 \(P_i,Q_i\) 的斜率所對應的點之間連邊。這樣問題可以轉化為,給你一張圖,要你選出一些不相交的二元組 \((e1_i,e2_i)\),滿足選出的二元組中兩兩之間沒有公共元素且 \(e1_i,e2_i\) 之間有公共點,要你求最多能選出多少個二元組。

針對上面的問題,我們首先大膽猜測:對於每個連通塊,假設連通塊中有 \(e\) 條邊,那么該連通塊中最多可以選出 \(\lfloor\dfrac{e}{2}\rfloor\) 個二元組,即,假設圖中有 \(k\) 個連通塊,第 \(i\) 個連通塊中有 \(e_i\) 條邊,那么答案就是 \(\sum\limits_{i=1}^k\lfloor\dfrac{e_i}{2}\rfloor\)

事實的確如此,考慮如何構造:對於每個連通塊,我們先對其進行一遍 DFS,也就是找出它的一棵 DFS 樹(雖然我們並不用顯示地將樹建出來,但是大體思想就是如此),然后對於每個點,有可能所有與其相連的邊已經全部匹配完,也有可能與其相連的邊中,恰有一條邊沒有被匹配(如果出現了多余兩條邊沒有被匹配,那么我們可以貪心地將這兩條邊配對,這樣肯定更優)。因此我們記 \(mch_u\) 表示與 \(u\) 相連的邊中,沒有被匹配的邊的編號,特別地,\(mch_u=0\) 則表示所有與 \(u\) 相連的邊都被匹配。那么我們考慮 DFS \(u\) 的一個兒子 \(v\) 時,分情況討論:

  • 如果 \(mch_v\ne 0\),則將 \(u,v\) 之間的邊與 \(mch_v\) 配對並令 \(mch_v=0\)
  • 否則,如果 \(mch_u\ne 0\),則將 \(u,v\) 之間的邊與 \(mch_u\) 配對並令 \(mch_u=0\)
  • 否則令 \(mch_u\)\(u,v\) 之間的邊的編號。

如此貪心下去即可,總復雜度 \(n\log n\),瓶頸在於求出所有出現過的斜率。可能可以做到 \(\mathcal O(n)\)

96. CF1609G A Stroll Around the Matrix

u1s1 感覺這個題其實還挺一眼的吧,不知道怎么被評到 3k 的.jpg(

首先考慮什么樣的路徑是最優路徑。我們先不妨假設我們先一直向右走,再一直向下走,即 \((1,1)\to(1,2)\to\cdots\to(1,m)\to(2,m)\to\cdots\to(n,m)\),但是這樣顯然不一定是最優解,因此考慮調整。調整的第一步顯然是將 \((1,m-1)\to(1,m)\to(2,m)\) 調整為 \((1,m-1)\to(2,m-1)\to(2,m)\),顯然后者代價比前者更優,當且僅當 \(a_2+b_{m-1}<a_1+b_m\)。再者就是將 \((1,m-2)\to(1,m-1)\to(2,m-1)\) 調整為 \((1,m-2)\to(2,m-2)\to(2,m-1)\),以及 \((2,m-1)\to(2,m)\to(3,m)\) 調整為 \((2,m-1)\to(3,m-1)\to(3,m)\),以此類推。按照這樣的方式繼續手玩下去可以發現,在最終的狀態中,假設我們在點 \((i,j)\),那么我們會往下走,當且僅當 \(j=m\),或者 \(i\ne n\)\(a_{i+1}-a_i<b_{j+1}-b_j\)

我們考慮設 \(pos_i\) 表示我們處於第 \(i\) 行時,會在哪個位置首次向下走,由於 \(n\) 很小並且題目中 \(a,b\) 序列都是下凸的,因此對於同一行 \(i\),必然存在一個斷點 \(j\),使得對於 \(j\) 左邊所有位置,當我們位於 \((i,j)\) 時都會向右走,而對於 \(j\) 右邊所有位置,當我們位於 \((i,j)\) 時都會向下走。且 \(pos\) 數組也是單調不降的。這樣一來問題就好辦了,由於 \(n\) 很小,因此對於每次修改,改完之后都可以直接線段樹二分修改 \(pos\) 數組,而答案即為 \(\sum\limits_{i=1}^n(a_i·(pos_i-pos_{i-1}+1)+\sum\limits_{j=pos_{i-1}}^{pos_i}b_j)\),這個也可以每次 \(\mathcal O(n\log m)\) 地求。比較麻煩的是要實現單點加求三階前綴和,用樹狀數組維護平方項、一次項和常數項能夠獲得常數較小的實現。

時間復雜度 \(\Theta(nm\log m)\)​。

97. NFLSOJ #795 【五校國集集訓 Day1】數學題(math)

首先考慮求出給定的 \(n\) 個向量的一組基 \(\mathcal B\)。那么非常顯然的一個性質是,對於不在 \(\mathcal B\) 中的向量,如果我們翻轉其中任意一位上的值,矩陣的秩肯定不會減小,因為矩陣仍存在線性無關的向量集合 \(\mathcal B\)。而我們發現,對於 \(\mathcal B\) 中的某些向量,這個性質也是成立的,比方說給出的向量集合為 \(\{100,011,111\}\),我們通過一遍線性基求出的基 \(\mathcal B = \{100,011\}\),但實際上,不論我們去掉三個向量中的哪一個,剩余部分的秩仍然是 \(2\),也就是說不論我們翻轉哪一個位置,矩陣的秩總是不降的。

那我們如何找出所有滿足“翻轉其中任意一位,矩陣的秩都不降”的向量呢?首先不在 \(\mathcal B\) 中的向量肯定要歸為其中,而對於在 \(\mathcal B\) 中的向量,我們假設 \(\mathcal B = \{x_{b_1},x_{b_2},\cdots,x_{b_k}\}\),並將所有不在 \(\mathcal B\) 中的向量都表示為 \(\mathcal B\) 中向量的線性組合,即假設 \(x_i=c_{i,1}x_{b_1}+c_{i,2}x_{b_2}+\cdots+c_{i,k}x_{b_k}\),其中 \(c_{i,j}\in\{0,1\}\),那么一個 \(x_{b_j}\) 符合上述要求,當且僅當 \(\exists i,s.t.c_{i,j}=1\),因為就算把 \(x_{b_j}\) 去掉之后,加入符合上述要求的 \(x_i\),得到的向量集仍是線性無關的。

而我們還可以發現一個性質,就是對於符合上面要求的向量,它們的答案都是相同的。具體來說我們考察每個 \(e_j\),即只有第 \(j\) 維為 \(1\) 的向量,如果它在 \(\mathcal B\) 生成的空間中,那么說明對於符合上面要求的向量,它與 \(e_j\) 的和也在 \(\mathcal B\) 生成的空間中,所有這些向量的答案的第 \(j\) 位就是 \(0\),否則所有這些向量第 \(j\) 位的答案就是 \(+\)

那對於別的向量,也就是去掉這個向量后,矩陣的秩必然減小的向量呢,首先一個顯然的性質:翻轉這些向量的任何一位后,矩陣的秩必然不增,因為去掉這個向量后,矩陣的秩減少 \(1\),而加入一個向量最多使矩陣的秩增加 \(1\)。那么翻轉什么樣的位后,答案減小 \(1\) 呢?我們還是考慮將 \(e_j\) 拆成 \(\mathcal B\) 中元素的線性組合。如果 \(e_j\) 無法表示,那么秩肯定不變,否則,如果 \(e_j\) 的表示中包含 \(x_i\),那么我們考慮再將 \(x_i+e_j\)​ 表示成 \(\mathcal B\) 中元素的線性組合,顯然 \(x_i+e_j\) 的線性組合中不會包含 \(x_i\),因為 \(x_i\) 的表達式中有個 \(x_i\)\(e_j\) 的表達式中也有個 \(x_i\),二者相加,在模 \(2\) 意義下消掉了,而其他向量的表示中也沒有 \(x_i\),因此矩陣的秩減小,否則不難說明矩陣的秩不變。

bitset 模擬上面的過程即可,時間復雜度 \(\dfrac{n^3}{\omega}\)​,如果視 \(n,m\)​​ 同階。

98. CF1530G What a Reversal

What a Problem!

首先考慮在變換前后有沒有什么量是不變的。顯然 \(1\) 的個數肯定不會變對吧,如果 \(s,t\)\(1\) 的個數不同那就直接 GG 了。這個直接特判一下即可。

我們記 \(s,t\)\(1\) 的個數為 \(m\),對於 \(k=0\)\(k>m\) 的情況,顯然只有 \(s,t\) 完全相同才有可能有解,這個特判一下即可。對於 \(k=m\) 的情況我們也需特判一下,這個大概就分翻一次、翻兩次、翻三次分類討論一下,可能細節略有點繁瑣。

下面重點討論 \(k<m\)​ 的情況,首先發現操作可逆,因此我們按照套路將 \(s,t\) 全變成一個字符串,然后正序輸出 \(s\) 的操作序列並倒序輸出 \(t\) 的操作序列。考慮一次操作的本質是什么,我們假設 \(s\)\(1\) 的位置分別是 \(p_1,p_2,\cdots,p_m\),方便起見假設 \(p_0=0,p_{m+1}=n+1\),我們再設 \(d_i=p_{i+1}-p_i-1\)​,那么可以發現一次操作等價於:

  • 選擇一個 \(i\in[0,m-k]\)​​,reverse 子段 \(d_{i+1},d_{i+2},\cdots,d_{i+k-1}\)​​,同時選擇一個 \(j\in[-d_i,d_{i+k}]\)​​,並令 \(d_i\)​​ 加上 \(j\)​​,\(d_{i+k}\)​​ 減去 \(j\)​​。

下面考慮怎樣構造,首先是 \(k\)​​​​ 是奇數的情況,我們考慮將兩個字符串都調整至 \(d_0=n-m,d_i=0(i\in[1,m])\)​​​​ 的狀態。我們首先先將 \(d_{k+1},d_{k+2},\cdots,d_m\)​​​​ 歸零,這個就每次選擇 \(j=d_{i+k}\)​​​​ 即可清空 \(d_{i+k}\)​​​​。然后我們考慮對於奇數步,我們令 \(i=0,j=d_k\)​​​​,這樣相當於翻轉 \(d_1\sim d_{k-1}\)​​​​ 並將 \(d_k\)​​​​ 清空全部送給 \(d_0\)​​​​;對於偶數步,我們選擇 \(i=1,j=d_{k+1}=0\)​​​​,這樣相當於翻轉 \(d_2\sim d_k\)​​​​​​​,不難發現這樣操作下去,\(d\)​​​​ 數組會依次發生以下變化(其中紅色代表對應的 \(d\)​​​​ 值已經變為 \(0\)​​​​:

  • \(d_0,d_{k-1},d_{k-2},\cdots,d_1,\color{red}{d_k}\)​​
  • \(d_0,d_{k-1},\color{red}{d_k}\color{black}{,d_{1},d_2,\cdots,d_{k-2}}\)​​
  • \(d_0,d_{k-3},d_{k-4},\cdots,d_1,\color{red}d_k\color{black},d_{k-1},\color{red}d_{k-2}\)
  • \(d_0,d_{k-3},\color{red}{d_{k-2}}\color{black}{,d_{k-1},}\color{red}{d_k}\color{black}{,d_1,d_2,\cdots,d_{k-4}}\)

不難發現在上面的過程中,咱們采用每一輪隔一個清一個的策略,即在奇數次操作依次將 \(d_k,d_{k-2},d_{k-4}\cdots,d_1,d_{k-1},d_{k-3},\cdots d_2\) 清空,由於 \(k\) 是奇數,故每個 \(d_i\) 都會被清到,因此進行 \(2k\) 次操作即可清空 \(d_1\sim d_k\),總操作數 \(2k+(m-k)=m+k\le 2n\)

接下來考慮偶數的清空,手玩一下可以發現 \(k\) 為偶數時不一定有解,因為不論你怎么 reverse,都有奇數位上的 \(d_i\)​ 之和不變,偶數位上也是如此,因此如果 \(s,t\) 奇數位上的 \(d\) 之和不同那就直接 GG 了,否則我們考慮如下構造方式:

  • 首先還是將 \(d_{k+1}\sim d_n\) 全部清空,構造方式同 \(k\) 為奇數的清空。
  • 然后在奇數輪我們還是選擇 \(i=0,j=d_k\),在偶數輪我們則選擇 \(i=1,j=-d_1\)

我們還是手動模擬一下上面的過程:

  • \(d_0,d_{k-1},d_{k-2},\cdots,d_1,\color{red}{d_k}\color{black},d_{k+1}=0\)
  • \(d_0,\color{red}{d_{k-1},d_k}\color{black},d_{k-2},\cdots,d_1,d_{k+1}\)
  • \(d_0,d_2,d_3,\cdots,d_{k-2},\color{red}{d_{k},d_{k-1},d_1}\color{black},d_{k+1}\)
  • \(d_0,\color{red}{d_2,d_1,d_{k-1},d_k}\color{black},d_{k-2},d_{k-3},\cdots,d_4,d_3,d_{k+1}\)

不難發現在上面的過程中,我們不斷把奇數位上的 \(d\) 丟給 \(d_{k+1}\),把偶數位上的 \(d\) 丟給 \(d_0\),因此最后得到的一定是 \(x,0,0,0,\cdots,0,y,0,0,\cdots\)​ 的形式。符合要求。

時間復雜度 \(n^2\),瓶頸在於每次操作后都要 reverse 重新算 \(p,d\)

99. CF1530H Turing's Award

咦?時隔 INF 天,tzc 竟然來補題解了,incredible(

首先考慮將整個過程倒過來處理,問題轉化為有一條數軸,你當前在 \(0\) 的位置,有一個排列,每次你可以走到相鄰兩個位置中的一個,如果那個位置上沒有數就在那個位置上填上 \(p_i\),求得到的 LIS 的最大值。

不難發現最優策略中,任意時刻肯定是恰有一個區間上有數,並且對於我們不欽定在 LIS 上的數我們肯定不會把它寫到紙上,否則從區間的一端走到另一端所需的代價會更大。考慮以此為狀態設計 DP。設 \(dpl_{i,j}\) 表示目前人在左邊,LIS 長度為 \(j\),最左邊的在 LIS 上的數為 \(i\),最右端的數的最小值,再設 \(dpr_{i,j}\) 表示目前人在右邊,LIS 長度為 \(j\),最右邊的在 LIS 上的數為 \(i\),最左端的數的最大值。考慮如何轉移,以 \(dpl\) 為例,\(dpr\) 道理類似:

  • 如果上一步還在左邊,那么有 \(dpl_{i’,j-1}\to dpl_{i,j}\),能進行這樣的轉移的條件是 \(i’>i\)\(pos_{i’}>pos_i\),其中 \(pos_x\) 表示 \(x\) 這個數在排列中的位置。
  • 如果上一步在右邊,那么有 \(i’\to dpl_{i,j}\)​,能進行這樣的轉移的條件是 \(dpr_{i’,j-1}>i\)​ 且 \(pos_{i’}-pos_i\ge j-1\)

直接枚舉 \(i,j,i’\)​ 轉移是三方的,不過注意到轉移可以寫成前綴 \(\max/\min\) 的形式,因此可以用樹狀數組找出最優決策點,復雜度變成了 \(n^2\log n\),但還是不夠。注意到題面中有個“排列 \(p\) 隨機生成”的條件。根據經典結論,隨機排列的 LIS 長度期望是根號級別的,因此我們猜測答案期望也是根號級別的,事實確實如此。實踐證明 \(j\) 枚舉到 \(285\) 即可,這樣復雜度就變成了 \(285n\log n\),常數略大,但由於時限很大,可以通過。

具體實現時還有不少細節需要注意,比如此題邊界條件非常值得思考,不能簡單地 \(dpl_{i,1}=dpr_{i,1}=i\),因為無論如何 \(p_n\) 都是要寫出來的,因此要分 \(p_n\) 在 LIS 上和不在 LIS 上處理。

100. P6845 [CEOI2019] Dynamic Diameter

簡單題。然鵝我一開始竟然不會,ymx 竟然一開始想 LCT,wjz 竟然一開始想動態 DP,震撼震撼(

考慮經典結論:點集的並的直徑屬於點集的直徑的並,這樣我們可以在 \(\mathcal O(\log n)\)​ 的時間內通過兩個點集 \(U,V\)​ 的直徑合並得到 \(U\cup V\)​ 的直徑,然后 DFS 序+線段樹維護區間直徑即可,修改一條邊的邊權時,我們只用更新包含這個點的區間的信息即可。

時間復雜度 \(n\log^2n\)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM