做題記錄節選
2020年是之前寫的東西,2021年及以后用來記錄一些做過的有意思的題目。
2021-5-4
洛谷P5369 [PKUSC2018]最大前綴和
考慮什么樣的一個前綴和最大,不難發現當且僅當這個前綴的所有真后綴之和大於等於 \(0\) ,去掉這個前綴后的序列的所有前綴之和小於 \(0\) ,設 \(f_s\) 表示 \(s\) 中所有數組成的序列所有后綴和大於等於 \(0\) 的方案數, \(g_s\) 表示 \(s\) 中所有數組成的序列所有前綴和小於 \(0\) 的方案數,這兩個都可以 \(\mathcal O(2^nn)\) dp 求出來,然后就可以統計出每一個集合成為最大前綴和的方案數,乘以權值加起來就行了。
2021-4-21
ARC072C Alice in linear land
可以先模擬一遍求出每個時刻操作前距目的地的距離。
因為可以任意變化,某一個時刻的答案為 NO 當且僅當小於等於當且距離小於等於所在距離全部都可以通過后面的操作到達目的地。
倒推出最大的滿足小於等於這個距離都可以到達目的地的值是多少,假如在后 \(k\) 步操作中值為 \(x\) ,后第 \(k+1\) 步操作走了距離 \(d\) ,那么 \([d,d+x]\) 顯然滿足條件,同時 \([0,x]\) 和 \([d-x,d]\) 也是可行的,這三個區間可以拼成連續的當且僅當 \(d-x\le x+1\) 即 \(x\ge \frac{1}{2}(d-1)\) ,所以就是說當 \(x\ge \frac{1}{2}(d-1)\) 時令 \(x\gets x+d\) 即可。
2021-4-1
CF1404D Game of Pairs
和 Koishi Loves Construction 一樣,上來先考慮求和, \(1\sim 2n\) 的和是 \(\frac{2n(2n+1)}{2}=n(2n+1)\equiv n\pmod {2n}\) ,這也就是說如果后手取到的和是 \(n\) 可以通過取反操作得到和為 \(0\) 的構造方法。
\(1\sim n\) 的和是 \(\frac{n(n+1)}{2}\) 。
當 \(n\) 是偶數的時候, \(\frac{n(n+1)}{2}\equiv \frac{n}{2}\pmod {n}\) ,在 \(\mod n\) 的意義下都不等於 \(0\) ,所以顯然不能通過加減若干 \(n\) 使得這個數字在 \(\mod 2n\) 意義下等於 0 ,所以先手 \(i\) 和 \(n+i\) 配對后手肯定輸。
當 \(n\) 是奇數的時候, \(\frac{n(n+1)}{2}=\frac{n+1}{2}n\) ,注意到特殊的配對方式,把 \(i\) 和 \(i+n\) 認為是同一個點,點的配對視為連邊,那么一個點度數恰好為 2 ,所以必然可以形成若干個環,由此無論先手如何配對,都可以較容易地構造出一個選擇方案,使得選擇的第 \(i\) 個數要么是 \(i\) 要么是 \(i+n\) ,最后得到的和要么是 \(0\) 要么是 \(n\) ,如果是 \(n\) 取反即可。
2021-3-30
CF1392E Omkar and Duck
可能是挺常用的技巧?題解鏈接。
CF750F New Year and Finding Roots
任意找到一個點 dfs 兩個方向取中點就可以找到最高點,從最高點一直向上跳,估計一下大概是深度大於等於某個值的時候通過 dfs 確定找的方向是否正確,深度小於某個值的時候通過 bfs 找根,最壞情況是一開始找到葉子,通過 dfs 確定 4 層的話消耗次數是 \(1+2+3+4=10\) ,最后三層通過 bfs 消耗次數是 \(7\) 的,但是其實沒有必要 \(7\) 次用完,如果 \(6\) 次沒有找到答案就是剩下的那個點了,所以只需要 \(16\) 次就可以 finding roots 了。
2021-3-29
CF1205C Palindromic Paths
網格圖黑白染色,相鄰的相同顏色的格子之間的關系可以直接詢問得到,由於 \(n\) 是奇數,並且只知道左上角和右下角的數字,所以有一部分格子不知道絕對數字只知道兩兩間的相對數字,關鍵是如何確定這些數字。
我搞了好久的分類討論,由於太復雜就不貼了,講一講你古題解里面的做法。
如果存在一條路徑 \(p_1,p_2,p_3,p_4\) 滿足 \(p_1\oplus p_2\oplus p_3\oplus p_4=0\) 那么 \(p_1=p_4\) 等價於 \(p_1,p_2,p_3,p_4\) 是回文路徑,由於左上角是 1 右下角是 0 ,所以必然存在 \(x\) 滿足 \(a_{x,x}=1,a_{x+2,x+2}=0\) ,此時這兩條路徑的異或值:
不同,所以一定存在一個異或為 0 的路徑,然后依次詢問就可以確定答案了。
CF1174F Ehab and the Big Finale
先問到根的距離,建出到根距離為查詢得到的答案的點的虛樹,那么答案一定在葉子上面,然后重鏈剖分,從根一直跳重兒子跳到底端,問距離就可以知道答案在重鏈的那個點往下走,然后使用 s 操作往下走一步,這樣就刪掉了一個重子樹,通過兩次將點數縮小為至少 1/2 ,可以過。
Dandandan 有一個更強的做法,分類討論,如果沒有兒子子樹大小大於 1/2 直接向下跳,否則重鏈剖分,從根一直跳重兒子跳到底端,問距離就可以知道答案在重鏈的那個點往下走,然后不使用 s 操作直接刪掉重兒子把那個點作為下次詢問直接遞歸即可,極端情況下是 1 次減小一半或者 2 次減小 2/3 ,次數大概是 \(2\log_3n\) 級別的?反正吊打我就對了。
2021-3-19
CF521D Shop
顯然乘法操作很容易貪心,如果要用加法操作,某一個位置的加法操作肯定從大到小進行,也就是說加法操作的進行順序是固定的,所以其實每次加法操作也可以理解為一個乘法操作,考慮賦值操作肯定只有一次有用,所以每個位置肯定找最大的賦值操作保留,賦值操作一開始放如果有增加的話相當於是一次加法操作,於是就可以直接從大到小貪心了。
需要注意的就是賦值操作如果選了一定要一開始放。
AGC023D Go Home
假設公交車一開始停在最靠邊的兩棟樓中間,正難則反,考慮最靠邊的兩棟樓,不難發現如果最左邊人數大於等於右邊,那么經過最左邊一定先於經過最右邊,此時達到最右邊的樓的時間一定是到達最左邊的樓的時間加上它們的距離,所以此時最右邊的人的目的就變成最小化到最左邊的樓的時間了,和最左邊的人的目的相同,所以可以理解為把它們趕到最左邊的樓里面去,如果最左邊人數小於右邊也是類似的,然后往下遞歸/循環即可。
2021-3-9
CF436E Cardboard Box
考慮貪心,將所有關卡按照 \(b_i\) 排序,那么如果第 \(i\) 個關卡拿了兩顆星那么前 \(i-1\) 個關卡一定至少都拿了一顆星(否則選前面某個關卡拿兩顆星更優),所以必然存在一個 \(k\) 滿足前 \(k\) 個關卡都拿過星,並且后面的關卡最多都只拿過一顆星,如果枚舉這個 \(k\) 那么就可以貪心地求解答案了,動態維護答案用個優先隊列之類地就比較好維護了。
2021-3-6
CF715E Complete the Permutations
如果排列 \(p,q\) 給定,那么使 \(p\) 變成 \(q\) 需要的最少次數可以這樣來求解:構建一張 \(n\) 個點的圖, \(p_i\) 向 \(q_i\) 連邊,這樣必然會形成若干個環,最少交換次數就是 \(n\) 減去環的數量。由此題目本質就是要讓你求形成環的數量為 \(i\) 的方案數。
雖說 \(p,q\) 並沒有完全補齊,不過還是類似上面的做法,讓 \(p_i\) 向 \(q_i\) 連邊,這樣會得到五種不同的形態:數形成的環(記作 A )、起點為數終點為數的鏈( B )、起點為數終點為 0 的鏈( C )、起點為 0 終點為數的鏈( D )、起點為 0 終點為 0 的鏈( E )。 A 可以不用管了,關鍵是把沒有確定的鏈拼成若干個環。
考慮 C ,這種鏈顯然不會和 D 接在一起,這種鏈可能的接法其實只有兩種,一種是 ECCC...CCCB ,另一種是自己形成環,可以把接在 E 后面的 C 和 E 綁在一起是做一個 E ,所以對於 C 只關心它自己形成了多少個環,對於 D 同理,可以把 C 和 D 使用背包合並起來,剩下的就只有 B 和 E 了,這兩個形成環還是很好處理的,然后再使用背包合並起來就可以求答案了,時間復雜度 \(\mathcal O(n^2)\) 。
2021-3-3
CF1446C Xor Tree
看到異或首先想到 Trie ,從 Trie 的根結點從上往下考慮,如果當前結點兩個孩子的 size 都大於等於 2 ,那么這兩個孩子肯定是單獨形成兩個連通塊,要形成一棵樹必須要讓它們連通,所以肯定是把某個孩子里面的數刪得只剩一個,這樣就可以遞歸求解了。
下面是之前寫的一句話題解里面的東西。
標題用了誇張的修辭,不要在意。
感覺都要變成做題記錄了。
好的,其實它就是做題記錄,並非所有題目都會寫在上面。
注意:可能不是實時更新,畢竟這人肯定是個鴿子。
下面的日期寫的是 \(\rm AC\) 時間。
咕咕咕
2020-6-11
[十二省聯考2019]騙分過樣例
題面:
\(T\) 組數據,每次給定一個數 \(x\) ,求 \(19^x\bmod 998244353\) 。
快速冪+擴展歐拉定理。
復習一下擴展歐拉定理:
\(T\) 組數據,每次給定一個數 \(x\) ,求 \(19^x\bmod\) 某個數的值。
如何求這個數?找到答案中最大值 \(1145099\) ,從其開始枚舉,每次檢驗一下前幾個數是否合法,程序運行得到,模數就是 \(1145141\) ,然后用之前做法即。
\(T\) 組數據,每次給定一個數 \(x\) ,求 \(19^x\bmod\) 某個數的值。
模數較大,先把所有詢問和答案配對,看有沒有挨得比較近的詢問,發現有以下兩個詢問和答案接近:
詢問 | 答案 |
---|---|
264708066 | 1996649514996338529 |
264708068 | 1589589654696467295 |
\(1996649514996338529\times 19\times 19-1589589654696467295=719200885258981741674\) ,分解一下這個數,得到 \(719200885258981741674=2\times3\times 23\times 5211600617818708273\) ,顯然模數就是 \(5211600617818708273\) ,注意一下這個數的兩倍會爆long long
,用 \(\mathcal O(1)\) 快速乘或者是unsigned long long
加龜速乘。
\(T\) 組數據,每次給定一個數 \(x\) ,求暴力求 \(19^x\bmod 998244353\) 導致爆int
后的值(即一直執行x=x*19%998244353
,其中x
的變量類型為int
)。
先用map
找到循環節,然后利用循環節求答案。
\(T\) 組數據,每次求 \([L,R]\) 中的每個數是否是質數。
最大的數據范圍點是 \([999999999999000000,1000000000000000000]\) ,先篩出所有 \(\sqrt{n}\) 再篩顯然過不去,考慮直接枚舉每個數用 \(\rm Miller\_Rabin\) 判斷即可(順便借此機會復習一下 \(\rm Miller\_Rabin\) )。
\(T\) 組數據,每次求 \([L,R]\) 中的每個數的莫比烏斯函數。
最大的數據范圍點是 \([999999999999000000,1000000000000000000]\) ,如何篩呢?先篩出 \([1,1000000]\) 內的質數,用這些質數去篩掉這部分內的數,然后篩后有四種情況:為 \(1\) 、為一個質數、為兩個不相等質數的乘積、為兩個相等質數的乘積。 \(1\) 判掉,質數用 \(\rm Miller\_Rabin\) ,相等質數乘積用 \(sqrt()\) 函數即可判斷。
\(T\) 組數據,每次求 \([L,R]\) 中每個數是否是給定質數 \(p\) 的原根。
當 \(p=998244353\) 時暴力判斷原根即可,原根判斷方法:一個數 \(x\) 是質數 \(p\) 的原根,當且僅當對於 \(\varphi(p)=p-1\) 的任意質因數 \(q\) ,都滿足 \(x^{\frac{\varphi(p)=p-1}{q}}\bmod p\ne 1\) 。
當 \(p=13123111\) 時要用一種特殊的方法做,引用題解里面的話:
首先,我們暴力找出其最小的一個原根(實際上任意一個原根都可以)。
接下來求出每個數以這個最小原根為原根的指標(即離散對數)。
然后判斷每個數的指標與 \(\varphi(p)\) (即 \(p-1\) )是否互質即可判斷這個數是否為原根。
但判互質這里需要一種類似於篩的東西。
考慮和上個點一樣先求出 \(p-1\) 的全部質因數,然后把這些質因數的倍數全部打個標記。
最后指標沒被打標記的就是原根。
\(T\) 組數據,每次求 \([L,R]\) 中每個數是否是給定質數 \(p\) 的原根(其中有一個 \(p\) 需要猜)。
還是引用題解原話:
考慮出題人會怎么卡你?肯定是把模數放在靠中間的位置。
因此,我們就從中間向兩邊枚舉!
然后對於枚舉到的數如何判斷呢?
首先依然是 \(\rm MillerRabin\) 判素數。
接下來,我們只驗證前 \(50\) 個答案,如果這個數的 \(\frac{p-1}{2}\) 此房為 \(1\) 但是這一位應該是原根,就說明 \(p\) 不是要求的模數。
找到模數為: \(1515343657\) 。
直接用 \(998244353\) 的暴力判斷方法即可。
[十二省聯考2019]春節十二響
先考慮簡單情況,假設只有一個根節點 \(1\) ,然后根節點連出去了兩條鏈該如何去做,可以把兩條鏈排個序,然后大的值和大的值合並,小的值和小的值合並,不難發現,這樣是最優的。
擴展到多叉,每次一樣地考慮將代表點 \(u\) 子樹的集合和代表其兒子 \(v\) 子樹的集合用如此方法合並。
不難發現代表以每個點為根的子樹的集合中的元素數量就是最長鏈,用長鏈剖分的思想, \(\mathcal O(1)\) 繼承重兒子信息,然后合並其他輕兒子,關鍵在於這個“集合”要如何實現,可以用數組,但是合並完所有信息后還要將當前點的值加入,於是復雜度就過不去了,最好應該是用堆,合並時一個個 \(\rm pop\) 掉即可,加值也很方便。
2020-6-10
[十二省聯考2019]異或粽子
前綴異或和后就變成了:任意選擇兩個數,求他們異或起來的前 \(k\) 大值。
用超級鋼琴的思路,設 \((x,l,r)\) 表示在 \([l,r]\) 中可以任選一個數和 \(x\) 異或后得到的值的集合,那么肯定會先選最大的,設 \(k\in [l,r]\) 滿足 \(a_x\oplus a_k\) 最大,那么從大往小考慮時必然會先選擇 \(a_x\oplus a_k\) ,然后將其拆分為 \((x,l,k-1)\) 和 \((x,k+1,r)\) ,至於如何求 \(k\in [l,r]\) ,可持久化Tire即可實現。
這題好像有復雜度更優的算法,據說和 \(k\) 無關,暫且沒有學習,加強版是:CF241B Friends,同樣的,這題也很類似:CF1055F Tree and XOR,以后有時間可以做做。
[九省聯考2018]IIIDX
首先建樹,規定 \(i\) 號點的父親是 \(\lfloor \frac{i}{k} \rfloor\) 。
如果 \(d_i\) 互不相同,從根節點開始貪心,從小到大地考慮每一個兒子,每次都是選最大的一部分給這個兒子(設這個兒子大小為 \(s\) ,那么把最大的 \(s\) 個 \(d_i\) 都分配給這個兒子及其子樹),同時遞歸下去即可得到答案。
若 \(d_i\) 存在相同的情況,那么就不可以這么貪心了,舉個例子:設最大的 \(s\) 個 \(d_i\) 為 \(\{6,7,8\}\) ,但是由於 \(6\) 可能存在多的,那么說不定分給這個兒子 \(\{6,6,7\}\) 還要更好些,它的兄弟選擇的優先級是比它子樹里除它外的所有節點要大的!
那么如何處理呢?假設當前能選的數為 \(\{6,6,7,8\}\) ,一個子樹的大小為 \(3\) ,那么我們肯定會選擇 \(\{6,6,7\}\) ,還是原來的那個原因:它的兄弟選擇的優先級是比它子樹里除它外的所有節點要大,必須要盡可能為它的兄弟預留空間。
具體實現如下:
先將 \(d\) 從小到大排序去重,統計每個值出現次數 \(cnt(x)\) ,對每個值統計一個 \(f(x)\) 表示大於等於 \(x\) 還沒被取的值的個數。
假設給某個節點匹配到了一個值 \(x\) ,那么比小於等於 \(x\) 的值 \(y\) 的 \(f(y)\) 都會減小這個節點代表的子樹大小那么多,但是這樣做的話大於 \(x\) 的值的 \(f\) 就沒有更新,由於有若 \(x>y\) ,那么 \(f(x)\le f(y)\) ,所以我們不妨規定實際上 \(x\) 的 \(f\) 值為 \(\min_{i=1}^xf(i)\) ,不難發現,這樣規定是對的。
每次選值的時候就在線段樹上二分找到滿足在剩下的數中最靠右的並且 $\min_{i=1}^kf(i)\le $ 子樹大小的 \(k\) ,然后將區間 \([1,k]\) 執行減去子樹大小的操作。
注意:在選取某個節點的值時,必須消去其父親對除它自己外所有 \(f\) 值的影響,即執行區間加父親子樹大小的操作,引用一篇題解里的話:
想象一下,如果不撤銷父親的影響的話,豈不是相當於別人特意給你占了座,結果你自己還不能坐上去?
因為一個節點的兒子都是連續的,所以我們在撤銷的父親的影響后,會馬上把不應該撤銷的部分給補上(兒子的子樹在不斷的加上來),所以不用擔心對之后的決策造成影響
[九省聯考2018]一雙木棋chess
這題主要考的就是狀態設置,如果設十維狀態肯定不行, \(10^{10}\) 直接爆空間,不難發現十維狀態之間是有一定關系的,即后面的數字一定小於等於前面的數字,不妨設 \(f(i,j)\) 表示有 \(i\) 個非負數字,第一個數字為 \(j\) ,后面的數字需滿足小於前面的數字的方案數,這樣的話就可以利用 \(f\) 來記錄狀態,將十個數字壓倒一個數字里面表示,就可以轉移了。
2020-6-7
[六省聯考2017]壽司餐廳
最大權閉合子圖模型。
將每個 \(d_{i,j}\) 視為一種物品,那么如果拿了物品 \(d_{i,j}\) ,若 \(i\ne j\) ,說明一定要拿物品 \(d_{i+1,j}\) 以及 \(d_{i,j-1}\) ,如果拿了物品 \(d_{i,i}\) ,說明選擇了 \(i\) 號壽司吃,一定會花費 \(a_i\) 元(因為付錢數量為 \(mx^2+cx\) ,若選擇了 \(i\) 號壽司, \(c\) 就一定會加一),如何表達 \(mx^2\) 呢?顯然可以加上 \(\max(a_i)\) 個物品,第 \(i\) 個物品花費為 \(mi^2\) ,若選了 \(d_{i,i}\) ,那么就必須選這其中的第 \(a_i\) 個物品。
建模后直接跑網絡流即可。
2020-6-6
上帝與集合的正確用法
寫這題是因為想去寫相逢是問候,但是這題太難的,還沒去寫。
擴展歐拉定理得到:
所以有:
遞歸下去即可得到答案。
2020-6-5
[六省聯考2017]分手是祝願
不妨把每個開關看做是一個長度為 \(n\) 的二進制數,若按這個開過燈 \(i\) 會改變,那么這個數的第 \(i\) 位就是 \(1\) ,否則是 \(0\) 。
這樣的話多次按開關就相當於是二進制數之間的異或,考慮將這些數一個個插入線性基里,不難發現,全部都會插入成功,因為這些數之間是線性無關的,每個數都有着獨一無二的最高位。
既然如此,如果每個開關最多按一次那么要將所有燈熄滅只有一種方法,兩次按同一個開關相當於沒按,題目轉化為:
給定 \(n\) 個開關,其中有 \(m\) 個開關要按奇數次,若剩余開關還需要按的次數少於 \(k\) ,那么就會直接按那 \(k\) 個開關,否則隨機一個開關按,問完成任務按開關的期望次數。
設 \(dp(i)\) 表示還有 \(i\) 個開關要按的最終的期望次數,轉移:
顯然直接高斯消元過不了,考慮 \(\mathcal O(n)\) 做。
觀察到有: \(dp(n)=dp(n-1)+1\) ,不妨設 \(dp(i+1)=a_idp(i)+b_i\) ,那么由原轉移方程可以得到:
歸納法得出 \(a_i=1\) ,直接去掉 \(a_i\) 即可得到:
其中 \(b_{n-1}=1\) 。
由此可以得到:
至此,得到了 \(\mathcal O(n)\) 求 \(dp(x)\) 的方法,至於求哪些開關是要按的,就用類似線性基的方法,開關編號從大往小掃,如果再掃到第 \(i\) 個開關時,第 \(i\) 盞燈還是亮的,就要按第 \(i\) 個開關,改變所有 \(i\) 的因子的燈的情況。
[六省聯考2017]摧毀“樹狀圖”
不妨按樹上兩條路徑的相對情況來分類討論:
情況一:兩條路徑存在點重合。
因為樹上兩個點之間只有一條路徑,所以如果有點重合,那么一定只會有一個點是公共點,我們可以把這一個點單獨拎出來作為根,不難發現所謂的兩條路徑可以視為 \(1\sim 4\) 條鏈,其中鏈的一端就是根,只需要記錄從根連出去的前四大鏈即可得到這種情況的答案。
情況二:兩條路徑不存在點重合。
不難發現必然存在一棵子樹使得一條路徑完全在這棵子樹內而另外一條路徑和這個子樹沒有交點,考慮枚舉每一棵子樹,規定這棵子樹內的路徑經過子樹的根,然后找到在這棵子樹內的最優路徑和子樹外的最優路徑。
不難發現,上面列出來所要求的都可以通過換根較容易地求出。
狀態如下(以下所說的路徑及鏈都可以退化為單點):
設 \(mx(u,k)\) 表示考慮在以 \(u\) 為根的子樹中,對於所有 \(u\) 的兒子 \(v\) 中 \(dp(v)\) 第 \(k+1\) 大的值。
設 \(cnt(u)\) 表示 \(u\) 的兒子數量。
設 \(dp(u)\) 表示考慮在以 \(u\) 為根的子樹中,去掉以 \(u\) 為一個端點的鏈后剩下的聯通塊數量的最大值。
設 \(fp(u)\) 表示考慮在以 \(u\) 為根的子樹中,去掉經過 \(u\) 點的某條路徑后剩下的聯通塊數量的最大值。
設 \(f(u)\) 表示考慮在以 \(u\) 為根的子樹中,去掉某條路徑后剩下的聯通塊數量的最大值。
轉移如下:
發現 \(f(u)\) 可能不太好轉移,因為對於 \(u\) 的兒子 \(v\) 里面的一條路徑,如果是經過 \(v\) 點的話,只考慮以 \(v\) 為根的子樹是不會考慮到 \(v\) 外面連着的 \(u\) 所在的連通塊造成的貢獻,而如果不經過 \(v\) 點的話, \(u\) 所在的連通塊是不會造成貢獻的,所以考慮多記錄點東西:
設 \(f_0(u)\) 表示考慮在以 \(u\) 為根的子樹中,去掉某條路徑后剩下的聯通塊數量的最大值;設 \(f_1(u)\) 表示認為刪去 \(u\) 點后 \(u\) 外面還有一個連通塊,去掉某條路徑后剩下的連通塊數量的最大值。
然后我們再假設 \(fmx(u)\) 表示對於所有 \(u\) 的兒子 \(v\) 中 \(f_1(v)\) 的最大值。
轉移就比較容易了:
好的,看看我們轉移用到了哪些東西: \(fmx(u)\) 、 \(mx(u,0)\) 以及 \(mx(u,0)+mx(u,1)\) 。
顯然,換根的時候只要記錄: \(fmx(u)\) 的最大次大, \(mx(u,0)\) 的最大次大次次大。
不難發現,更新答案的時候要用到 \(mx(u,0\sim 3)\) ,所以 \(mx(u,0)\) 其實要記錄前四大。
[六省聯考2017]期末考試
發現當出成績的最晚時間確定時,學生和老師的不愉快度都是很好算的,當出成績的最晚時間減一時,很容易就可以維護學生的不愉快度和老師的不愉快度,需要維護這些東西:可以推遲公布成績的課程總和,需要提前公布成績的課程總和,學生不愉快度的總和。利用前綴和等操作即可維護,然后從大往小枚舉出成績的最晚時間。
2020-5-29
[APIO2014]連珠線
用來學習換根dp的一道題。
首先轉化題意,兩個操作可以轉化為:
- \(\rm Append(w, v)\) :一個新的珠子 \(w\) 和一個已經添加的珠子 \(v\) 用紅線連接起來。
- \(\rm Insert(w, u, v)\) :一個新的珠子 \(v\) 和一個已經添加的珠子 \(v\) 用藍線連接起來,同時一個新的珠子 \(w\) 和 \(v\) 用藍線連接起來。
如果確定了剛開始擁有的點將其作為根,那么題意再次轉化:
給定一棵有根樹,每次可以選擇依次相連的三個深度依次遞增的點,並刪去連接着這三個點的兩條邊,執行若干次后,最終被刪除的邊邊權和最大是多少。
考慮dp,設 \(dp_{u,0}\) 表示考慮完以 \(u\) 為根的子樹,其中 \(u\) 到它父親的邊不必被刪去能獲得的最大權值; \(dp_{u,1}\) 表示考慮完以 \(u\) 為根的子樹,其中 \(u\) 到它父親的邊必須被刪去能獲得的最大權值,設 \(w_u\) 表示 \(u\) 和他父親連邊的邊權,轉移就比較顯然了:
方便起見,再設一個 \(dp_{u,2}=\max(dp_{u,0},dp_{u,1}+w_{u})\) ,那么轉移:
最后答案就是 \(dp_{root,0}\) 。
這是在根確定的時候我們得到的轉移方程,接下來的問題就是換根時如何改變dp值了。
假設當前根是 \(u\) ,然后根要從 \(u\) 換為 \(v\) (其中 \(v\) 是 \(u\) 的兒子)首先改變 \(w\) ,然后更新dp值: \(dp_{u,0}\) 直接減去 \(dp_{v,2}\) 即可,對於處理 \(dp_{u,1}\) 時需要的取 \(\min\) 操作,我們可以記錄一個最小值和一個次大值,如果 \(dp_{v,2}-(dp_{v,0}+w_v)\) 是最小值,那么更新 \(dp_{u,1}\) 是就用次小值更新,否則就用最小值,然后更新 \(dp_{u,2}\) ,接着用 \(dp_{u,2}-(dp_{u,0}+w_u)\) 來更新 \(v\) 的最小次小值,最后更新 \(v\) 的dp值即可實現換根。
還有要注意的是,換完根后要換回來。
求出以每個點作為根時的dp值,那么最終答案就是每個點作為根時答案的最大值。
「NOIP模擬賽」小奇的倉庫
用來學習換根dp的一道題。
先考慮確定根時如何做。
設 \(sz_{i,j}\) 表示以 \(i\) 為根的子樹中到 \(i\) 距離在模 \(16\) 意義下為 \(j\) 的點的數量, \(sm_i\) 表示以 \(i\) 為根的子樹中到 \(i\) 的距離和,那么某個根的答案就是 \(sm_{root}+\sum_{i=0}^{15}sz_{root,i}\times((i\oplus m)-i)\) 。
考慮換根,發現直接做就行了,因為只有加減。。。
最后要注意的就是:題目中問的是 \(i\) 到其它所有星球的花費時間總和,所以要記得減掉 \(m\) 。
Fox And Travelling
先拓撲排序求出所有可以被遍歷到的點,如果有環就不行,所以最后可以被遍歷到的點一定組成了一座森林,對於森林中的某棵樹,如果它掛在不可被遍歷到的點上,就把它視為有根樹,根為和不可遍歷到的點相連的那個點,否則就把它視為無根樹。
對於一棵有根樹,我們設 \(dp_{i,j}\) 表示以 \(i\) 為根的子樹中遍歷 \(j\) 個點的方案數,考慮將 \(v\) 並入 \(u\) :
特殊的,一開始的 \(sz_u\) 設為 \(0\) , \(dp_{u,0}\) 設為 \(1\) ,最后再將 \(sz_u\) 加一,同時 \(dp_{u,sz_u}=dp_{u,sz_u-1}\) ,因為如果選了 \(sz_u\) 個點,相當於是將整棵子樹遍歷,此時要考慮到點 \(u\) 本身。
對於一棵無根樹,我們可以枚舉它的根,對於一個遍歷到的點的數量為 \(s\) 的方案數,除非 \(s=sz_{root}\) ,我們發現它恰好被多算了 \(sz_{root}-s\) 次,直接除回去就行了。
最后的答案就是把森林里每棵子樹地答案做一遍背包合並即可。
2020-5-27
Stranger Trees
矩陣樹定理。
矩陣樹定理求的是這個:
對於某條邊,如果它屬於原圖,那么設這條邊的邊權是 \(x\) ,否則設這條邊邊權為 \(1\) ,那么求出來的就是一個多項式,然后 \(x^o\) 的系數就是 \(k=o\) 時的答案。
顯然不好直接求,帶入 \(n\) 個值后高斯消元出最后的多項式。
[JSOI2018]潛入行動
樹形背包,顯然沒有黑題難度,估計是惡評。
設 \(dp_{i,j,0/1,0/1}\) 表示處理完了以 \(i\) 為根的子樹,里面使用了 \(j\) 個監聽設備,其中第 \(i\) 號節點是否存在監聽設備,是否被監聽設備覆蓋的方案數,考慮將子樹 \(v\) 並入 \(u\) :
時間復雜度: \(\mathcal O(nk)\) 。
[POI2014]HOT-Hotels及其加強版
設 \(f_{i,j}\) 表示在 \(i\) 的子樹內,離 \(i\) 距離為 \(j\) 的點數,設 \(g_{i,j}\) 表示在 \(i\) 的子樹內,滿足 \(\operatorname{dist}(x,i)=\operatorname{dist}(y,i)\) 並且 \(\operatorname{dist}(\operatorname{lca}(x,y),i)+j=\operatorname{dist}(\operatorname{lca}(x,y),x)\) 的點對 \((x,y)\) 的數量。
考慮一棵子樹一棵子樹地合並,將 \(v\) 並入 \(u\) :
考慮到狀態第二維和深度有關,直接長鏈剖分優化即可,注意 \(g\) 是反着來的,空間建議開大一點。
Dominant Indices
用來學習長鏈剖分優化dp的一道題。
狀態都設好了,直接轉移:
長鏈剖分優化即可。
Lomsat gelral
用來學習 \(\rm dsu\ on\ tree\) 的一道題,相當於是模板,就不說了。
Don't fear, DravDe is kind
一道假的黑題,難度大概藍?
顯然卡車 \(u\) 和卡車 \(v\) 可以放到一起必須要滿足 \(c_u+l_u+r_u=c_v+l_v+r_v\) ,可以開一個桶,里面存儲這所有可以放大一起的卡車,然后一個桶一個桶地考慮,可以把卡車 \(u\) 抽象為一個區間 \([l_u+1,l_ u+c_u]\) ,然后題目便轉化為給定若干個區間,選出一些區間使得其恰好填滿整個位置,最大化權值和,直接dp就行了,然后要記錄轉移。
一種復雜度可能不怎么優的做法:
卡車 \(v\) 可以接在卡車 \(u\) 后面當且僅當 \(l_u+c_u=l_v\) 並且 \(r_u=r_v+c_v\) ,直接用一個二維的 \(map\) , \(q_{x,y}\) 記錄當 \(l+c=x,r=y\) 時能達到的最大權值和,在轉移的時候順便記錄一下就行了。
2020-5-25
選舉預測
神仙題.jpg
如果 \(u\) 贏過 \(v\) ,那么我們就連一條從 \(u\) 到 \(v\) 的有向邊,那么就會形成一張有向圖。
首先,在同一個點雙連通分量里面,任何點都可以打敗其他所有點,所以貌似可以縮點?但是對於沒有任何關系的點咋辦?我們可以讓它們間有關系!
如果點 \(u\) 和點 \(v\) 沒有連邊,我們就在它們之間連一條雙向邊(即 \(u\) 到 \(v\) 連一條, \(v\) 到 \(u\) 連一條),表示 \(u\) 可以打敗 \(v\) , \(v\) 可以打敗 \(u\) ,操作后還是滿足在同一個點雙連通分量里面任何點都可以打敗其他所有點。
然后再縮點,縮完點后就是一張有向無環圖,找到入度為 \(0\) 的點就是答案。
復雜度 \(n^2\) ,顯然過不了,考慮縮完點后的圖有什么性質。
由於縮完點后任何點之間都有連邊,所以只會出現恰好一個入度為 \(0\) 的點!考慮在不連完所有邊的情況下(即在原圖下)找到答案。
可以先找到一個必勝的點,那么這個點最終一定被縮成了最后那個入度為 \(0\) 的點,然后從該點開始 \(\rm bfs\) ,設該點為 \(u\) ,如果原圖中不存在一條 \(u\) 到 \(v\) 的邊,那么處理完后的圖必然存在一條 \(v\) 到 \(u\) 的邊,那么 \(u\) 和 \(v\) 必然縮成了一個點,否則縮完點后 \(u\) 所在的點的入度就不是 \(0\) ,於是我們就把點 \(v\) 加入隊列繼續 \(\rm bfs\) 。
然而,復雜度還是 \(n^2\) ,因為我們 \(\rm bfs\) 是掃到的邊集是題目中給出的 \(m\) 條邊的補集,它是 \(n^2\) 級別的!
可以用鏈表優化,這樣原本已經在隊列里的點就不會再次被掃到,復雜度降為 \(\mathcal O(n+m)\) 。
完結撒花。
2020-5-23
[APIO2016]煙火表演
好的,這輩子題解都不可能只有一句話了。
設 \(dp_{i,j}\) 表示以 \(i\) 號節點為根的子樹到 \(i\) 的父親的距離全部修改為 \(j\) 所需要的最小花費。
轉移:
設 \(g_{u,k}=\sum_{v\ is\ u'son}dp_{v,k}\) ,那么:
顯然直接掃復雜度太劣了,如何優化?把 \(dp_{u,s}\) 看做是一個自變量為 \(s\) 的函數,觀察這個函數的性質。
首先,葉子結點的函數圖像一定是斜率為 \(-1\) 的一條折線加上斜率為 \(1\) 的一條折線。
然后從葉子節點手推一下,可以得到以下幾個性質:
- \(dp_u\) 和 \(g_u\) 為下凸函數。
- 由 \(g_u\) 可以直接推得 \(dp_u\) 。
- \(dp_u\) 和 \(g_u\) 函數下降段斜率最大為 \(-1\) ,上升段斜率最小為 \(1\) 。
假設函數 \(g_u\) 在 \([L,R]\) 段取值為最小值,由 \(g_u\) 推得 \(dp_u\) 的方法如下:
- 將函數在 \([1,L]\) 的折線往上平移 \(val_u\) 個單位。
- 將函數在 \([L,R]\) 的折線往右平移 \(val_u\) 個單位。
- 將函數在 \([R,+\infty]\) 的折線往右平移 \(val_u\) 個單位並把斜率改為 \(-1\) 。
這時空出了一段斜率為 \(-1\) 的折線,直接連上即可。
還有個性質: \(g_u\) 最右段的斜率是 \(u\) 的兒子數。
但是還有個問題:如何表示這個函數?
我感覺這題最妙的地方就是這里:用轉折點的橫坐標表示!
我們規定從左往右每經過一個轉折點斜率就加 \(1\) ,那么:
- 函數相加就是轉折點的並(可以在紙上推一下)。
- 從 \(g_u\) 轉到 \(dp_u\) 相當於是先把橫坐標最大的兒子數個的轉折點彈出,然后把平行段的 \([L,R]\) 取出,插入 \([L+val_u,R+val_u]\) ,即再彈出兩個橫坐標最大的兩個轉折點,把它們加上 \(val_u\) 后再插回去。
那么要實現:
- 合並兩個點集。
- 彈出權值最大的點。
- 插入點。
於是,便自然而然地想到可並堆。
完結撒花!
2020-5-22
Steps to One
好的,莫比烏斯反演+期望dp。
另一種做法(非dp):
設答案是 \(E(x)\) ,最終長度大於等於 \(k\) 的概率為 \(P(k)\),那么:
考慮枚舉前 \(i-1\) 個數的 \(\gcd\) 。
時間復雜度 \({\mathcal O(m)}\) 。
Little Sub and Piggybank
貪心+dp。
設 \(dp_{i,j}\) 表示這次在第 \(i\) 天買了物品,上次買物品是第 \(j\) 天的最大獲利。
貪心地想,要讓買第 \(i\) 個物品的門檻盡量低,要讓買下一個物品的能夠達到的水平盡量高,我們當然希望在 \(j+1\sim i\) 天內,投幣數量為 \(\frac{w_i}{i-j}\) 。
於是得到轉移:
優化一下,設 \(dp_{i,j}\) 表示這次在第 \(i\) 天買了物品,上次買物品是 \(j\sim i-1\) 天的最大獲利。
轉移:
答案:
Flipping Game
計數dp。
設 \(dp_{i,j}\) 表示當前行有 \(i\) 盞燈需要改變,還要操作 \(j\) 輪最后達成要求的方案數。
轉移就很顯然了:
初始化:
[AGC030D] Inversion Sum
神仙題。
居然有人把概率dp出成了計數dp。
直接計數不好做,考慮轉概率dp。
設 \(dp_{i,j}\) 表示在經過了當前若干操作后 \(a_i>a_j\) 的概率。
假如出現了交換 \(u,v\) 的操作,相當於是以 \(50\%\) 的概率執行,所以轉移:
最后答案就是:
2020-5-20
Misunderstood … Missing
未來費用的一道好題。
先放上翻譯:
打怪,有 \(n\) 輪,一開始用兩個參數 \(A\) 和 \(D\) ,初始值都是0,每輪開始時執行操作 \(A=A+D\) ,然后第 \(i\) 輪有以下幾種操作選擇:
- 造成傷害 \(A+a_i\) 。
- 令 \(D=D+b_i\) 。
- 令 \(A=A+c_i\) 。
最大化造成傷害之和。
前面的 \(2\) 和 \(3\) 操作會影響后面的操作 \(1\) ,考慮反着dp,設 \(dp_{i}\) 表示處理完了 \(i+1\sim n\) 的操作能造成的最大傷害,但是我們並不知道選擇操作 \(2\) 和 \(3\) 會造成多少傷害,所以還要記錄一些東西。
假設在 \(i+1\sim n\) 這些操作中選了 \(j\) 個操作 \(1\) ,這些操作中選的操作 \(1\) 所在的操作位置之和為 \(k\) (即 \(k=\sum_{l=1}^jpos_l\) ),那么操作 \(2\) 造成的傷害就是 \((k-i\times j)\times b_i\) ,操作 \(3\) 造成的傷害就是 \(j\times c_i\) 。
轉移如下:
Magic Gems
矩陣快速冪加速dp。
這題一開始想復雜了,上來直接推組合數,得出答案:
然后就不會寫了。。。
看完題解后才發現自己完全想復雜了,直接dp,設 \(dp_i\) 表示分解成 \(i\) 顆寶石的方案數,轉移:
記錄后 \(m\) 位,矩陣快速冪就行了。
所以說題目要更難的話建議直接給這個式子:
那估計要推蠻久。
Comparing Your Heroes
狀壓dp。
設 \(vis_{s}\) 表示在選出點集 \(s\) 后接下來能選的點集, \(dp_{s}\) 表示選出點集 \(s\) 的方案數。
轉移:
Makoto and a Blackboard
先將 \(n\) 分解質因數,假設 \(n=\prod_{i=1}^mp_i^{h_i}\) 。
將每一個質因數分開考慮。設 \(dp_{w,i,j}\) 表示經過 \(w\) 次操作(每次操作把 \(i\) 隨機變成 \([0,i]\) 中的一個數)后 \(i\) 變成 \(j\) 的概率 ,那么答案是:
轉移:
初始化:
Jongmah
貪心+dp。
顯然, \(\{1,2,3\}\times 3\) 和 \(\{1,1,1\},\{2,2,2\},\{3,3,3\}\) 沒有任何區別,所以相鄰的三個組成一對可以認為最多只會組兩次。
設 \(dp_{i,j,k}\) 表示考慮完了前 \(i\) 種麻將,其中組成了 \(j\) 對 \(\{i-1,i,i+1\}\) ,組成了 \(k\) 對 \(\{i,i+1,i+2\}\) 。
設 \(sum_i\) 表示第 \(i\) 種麻將的數量,轉移:
初始化:
答案:
[NOIP2018模擬賽] 小P的技能
蠻妙的一道題,沒有獨立想出來。
題意就是詢問 \(n\) 個點的二叉樹深度大於等於 \(k\) 的方案數。
設 \(dp_{i,j}\) 表示 \(i\) 個點的二叉樹深度小於等於 \(j\) 的方案數。
轉移:
初始化:
答案:
Array Without Local Maximums
相鄰三個數相鄰大小關系唯一不合法的情況就是:
設 \(dp_{i,j,sta}\) 表示填完前 \(i\) 個數組,最后一個數字為 \(j\) ,狀態為 \(sta\) 的所有方案,其中當 \(sta=0\) 時, \(a_{i-1}>a_i\) ,當 \(sta=1\) 時, \(a_{i-1}=a_i\) ,當 \(sta=2\) 時, \(a_{i-1}<a_i\) 。
轉移:
初始化:
最后答案是:
Tree with Maximum Cost
有點厚顏無恥地說着這題是換根dp。
樹形dp/換根dp。
考慮換根的影響,如果根從 \(fa_u\) 到 \(u\) ,改變值為 \(sz_{root}-2sz_u\) ,直接 \(O(n)\) 求出 \(sz\) 然后再 \(O(n)\) 計算答案就行了。
[ABC118D] Match Matching
數位dp/背包dp。
設 \(dp_{i,j}\) 表示能否用 \(j\) 根火柴棒拼出 \(i\) 位,設 \(us_k\) 表示第 \(k\) 個數字需要的火柴棒數量,轉移:
然后貪心,先選位數盡量大,再選高位盡量大,判是否可行就行了。
注意細節,不要讓數組越界。
Flood Fill
區間dp,先把相鄰相同顏色合並,記 \(dp_{l,r}\) 表示將 \([l,r]\) 塗成相同顏色的最小步數,轉移:
Colorful Bricks
相同顏色歸為一起,第一種顏色有 \(m\) 種選法,其他顏色有 \(m-1\) 種選法,然后再乘以把 \(n-(k+1)\) 個相同的球丟到 \(k+1\) 個盒子里去(允許盒子為空)的方案數。
答案為:
Pie Rules
設 \(dp_{i}\) 表示先手從 \(i\) 取到 \(n\) 可以獲得的最大利益,設 \(sum_i\) 為 \(\sum_{j=i}^na_i\) ,轉移如下:
博弈論
把之前博弈論的題目也放進來吧,反正也算是題解,不過 \(\rm AC\) 時間倒是忘了。
洛谷P3185 [HNOI2007]分裂游戲
把第\(i\)個瓶子了的豆子看作是數量為\(n-i-1\)的一堆石子,那么每次操作相當於是將一堆石子變成數量比它少的兩堆石子,由於\(2\le n\le 21\)很小,直接算出數量為\(1\dots n-1\)的石子的\(SG\)函數值,用\(SG\)定理,看異或起來是不是\(0\)就行了。
輸出方案直接枚舉選哪三個,判一下選完后的\(SG\)函數值是否合法就行了。
洛谷P5675 [GZOI2017]取石子游戲
博弈論加計數,考慮動規,記\(dp_{i,j}\)表示選出的石子堆包含編號為\(i\)的石子且石子數量異或起來為\(j\)的方案數,若編號為\(i\)的石子堆數量為\(a_i\),那么答案便是\(\sum_{i=1}^{n}(dp_{i,0}+\sum_{j=a_i+1}dp_{i,j})\),記值域最大為\(x\),時間復雜度\(O(n^2x)\)。
洛谷P3480 [POI2009]KAM-Pebbles
相當於是對相鄰兩堆石子的差做階梯NIM游戲。
poj1740 A New Stone Game
用手玩和打表等方法可以猜出以下結論(其實我也沒有好方法找結論的):
若\(n\)為偶數且恰好可以分成\(n/2\)份使得每份的兩堆數量相等,先手必敗;否則先手必勝。
證明:
若\(n\)為奇數,排序后可以保證\(a_n>(a_{n-1}-a_{n-2})+(a_{n-3}-a_{n-4})+\dots+(a_2-a_1)\),直接把\(a_{n-2k}\)變成\(a_{n-2k+1}\),剩下的丟掉就可以變成必敗態了。
若\(n\)為偶數,排序好可以保證\(a_n>(a_{n-1}-a_{n-2})+(a_{n-3}-a_{n-4})+\dots+(a_3-a_2)+a_1\),直接把\(a_{n-2k}\)變成\(a_{n-2k+1}\),剩下的拿到\(a_1\)就變成必敗態了。
必敗態無論如何都不可能變成必敗態。
當\(n=0\)時,也滿足必敗態的要求。
所以原結論成立。
洛谷P2599 [ZJOI2009]取石子游戲
此神仙題不可做(確信
記\(L_{l,r}\)表示如果在\(l\)到\(r\)這個區間左邊添上一堆石子數量為\(L_{l,r}\)的石子堆時先手必敗,記\(R_{l,r}\)表示如果在\(l\)到\(r\)這個區間右邊添上一堆石子數量為\(R_{l,r}\)的石子堆是先手必敗。
首先證明\(L_{l,r}\)和\(R_{l,r}\)唯一,假設\(L_{l,r}\)存在兩個取值\(x,y(x<y)\),那么當添上去的石子堆數為\(y\)時先手可以把\(y\)拿成\(x\),換成后手拿,此時后手必敗,先手必勝,與假設矛盾(當添上去石子數為\(y\)時先手必敗),所以\(L_{l,r}\)唯一,\(R_{l,r}\)同理。
接下來證明\(L_{l,r}\)和\(R_{l,r}\)存在,假設\(L_{l,r}\)不存在,即無論在左邊添上去的石子數量為多少,先手都必勝,假設左邊添上\(x\),那么先手必然不會拿左邊的這個\(x\),因為拿了后還是必勝態,所以先手會從右邊拿,那么在拿完后無論\(x\)為多少都是必敗態,后手如果拿了左邊的\(x\)得到的還是必敗態,與“無論\(x\)為多少都是必敗態矛盾”,所以\(L_{l,r}\)存在,\(R_{l,r}\)同理。
再證明一些結論吧:
引理一:
若\(L_{l,r}=0\),那么\(R_{l,r}=0\)(\(R_{l,r}=0\)時同理)。因為\(L_{l,r}=0\),局面為\((0,[l,r])\)即\(([l,r])\)時先手必敗。假設\(R_{l,r}\ne 0\),那么先手可以直接把右邊拿成\(0\),此時局面變成\(([l,r])\),后手操作,所以后手必敗,與原先假設先手必敗矛盾,所以結論成立。
考慮\(L_{l,r}\)如何轉移(\(R_{l,r}\)同理):
方便起見,記\(L=L_{l,r-1},R=R_{l,r-1},x=a_r\)。
\(L_{l,r}=0\)。相當於原本就是必敗態。
\(L_{l,r}=x\)。由必勝必敗態的定義可以知道當石子數量為\((0\sim L-1,[l,r-1])\)或者\(([l,r-1],0\sim R-1)\)時先手必勝。可以在左邊添上一堆數量為\(x\)的石子,此時先手從哪一邊拿石子,后手就從另一邊拿相同數量的石子,此時必然會有一堆先被拿完,拿完后操作方變成后手,局面變為\((0\sim L-1,[l,r-1])\)或\(([l,r-1],0\sim R-1)\),后手必勝。
\(L_{l,r}=x-1\)。假設先手拿左邊,左邊剩\(y\)個石子:若\(y<R\),后手可以直接把右邊拿成\(y\),變成\(\mathsf{Case 2}\)里面的情況;若\(y\ge R\),后手把右邊拿成\(y+1\),回到\(\mathsf{Case 3}\)。假設先手拿右邊,右邊剩\(y\)個石子:若\(y=R\),如果\(R\ne 0\),左邊剩余石子數必然大於\(0\),后手直接把左邊拿完,變成\(\mathsf{Case 1}\),否則\(R=0\),由引理一得到\(L=0\),不存在\(R<x\le L\),即該情況不存在;若\(y<R\),那么先手上一步至少拿了兩個石子(\(y\ge R+1\to y\le R-1\)),左邊石子數量必然大於\(y\),后手可以把左邊拿成\(y\),變成\(\mathsf{Case 2}\);若\(y>R\),后手把左邊拿成\(y-1\),回到\(\mathsf{Case 3}\)。
\(L_{l,r}=x+1\)。這個和\(\mathsf{Case 3}\)類似,建議讀者先自己想想。假設先手拿左邊,左邊剩\(y\)個石子:若\(y=L\),如果\(L\ne 0\),右邊剩余石子數必然大於\(0\),后手直接把右邊拿完,變成\(\mathsf{Case 1}\),否則\(L=0\),由引理一得到\(R=0\),不存在\(L\le x<R\),即該情況不存在;若\(y<L\),那么先手上一步至少拿了兩個石子(\(y\ge L+1\to y\le L-1\)),右邊石子數量必然大於\(y\),后手可以把右邊拿成\(y\),變成\(\mathsf{Case 2}\);若\(y>L\),后手把右邊拿成\(y-1\),回到\(\mathsf{Case 4}\)。假設先手拿右邊,右邊剩\(y\)個石子:若\(y<L\),后手可以直接把左邊拿成\(y\),變成\(\mathsf{Case 2}\);若\(y\ge L\),后手把左邊拿成\(y+1\),回到\(\mathsf{Case 4}\)。
\(L_{l,r}=x\)。分類討論后不難變成以上四種\(\mathsf{Case}\),請讀者自行思考。
\(R_{l,r}\)和\(L_{l,r}\)的求解類似,不再贅述。
最后只要判斷一下\(L_{2,n}\)是否等於\(a_1\)就可以判斷勝負了。