ATCoder 做題記錄


AGC 備忘錄

Notes

  • Beginner:過於簡單因此沒進備忘錄的題
  • Easy:能在幾分鍾內秒掉或者一眼看出了做法的題
  • Medium:自己想出了正解或大部分思路的題,或一些正解不難但很有迷惑性的題。
  • Hard:自己只想到了個大方向或者束手無策的題
  • Insane:完全想不到,幾乎理解不能的題
  • 加號:該難度中相對難的題。
  • 減號:該難度中相對簡單的題。
  • 前一個難度的加號約等於后面一個難度的減號,用於區分個人差。

AGC001

D (Easy)

一段長度為 \(i\) 的回文事實上就是限制了 \((1,i),(2,i-1),(3,i-2)\) 這樣的字符必須相同。

注意到一段長度為 \(L\) 的區間會給這個序列加 \(\lfloor\frac{L}{2}\rfloor\) 個限制,而我們至少需要 \(n-1\) 個限制,所以顯然 \(n\) 是奇數就一次都不能浪費,也就是 \(a,b\) 都只能有一個長度為奇數的段了。

然后如果 \(n\) 是偶數我們就可以浪費一次,所以可以分為 \(a\)\(0\)\(2\) 個長度為奇數的。

一個非常強的構造策略是我先輸出一個 \(1\),然后全部復讀,不難發現這樣對於偶數就是合法的,但是錯了一位,把錯的那位放到開頭末尾和奇數的段即可。

E (Easy+)

組合意義。

\((-x,-y)\) 走到 \((z,w)\) 的合法路徑數就是 \(\binom{x+y+z+w}{x+z}\)

因此我們直接把走到起點的路徑數設為 \(1\) 然后遞推一遍,在所有終點處統計貢獻。

這樣求出的是 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}f(i,j)\),不要忘記稍微處理一下。

F (Hard)

考慮排列中值為 \(i\) 的位置為 \(a_i\)

那么我們能交換 \(a_i\)\(a_{i+1}\) 當且僅當 \(|a_i-a_{i+1}|\geq k\)

於是我們發現,如果 \(|a_i-a_j|<k\),無論怎么樣它們都不能被交換,也就是說它們的關系已經被固定。

大膽猜測固定所有 \(|a_i-a_j|<k\) 的對同樣是構造排列的充分條件,同樣可以證明。

因此我們轉化回去,就變成了給一個序列,差 \(<k\) 的下標的相對關系已經固定,求可能的最小排列。

這個東西就可以建 DAG 了(然后這里粉兔說明了一些題解的問題)。

於是一個點的入度就是 \(a_{i-k}\sim a_{i+k}\) 里面比它大的數的數量,直接暴力上數據結構即可。

AGC002

D (Easy)

整體二分基礎練習題。

E (Medium)

考慮把博弈的網格畫出來,然后找到一個厲害的結論:一個點和它左下的勝負態相同。

然后直接搞一下就做完了。

F (Hard)

\(f_{i,j}\) 為放 \(i\) 個白球后放完 \(j\) 種其它顏色球的方案數。

然后每次可以在最前面放一個白球或者在后面的位置隨便放 \((k-1)\) 個同一種顏色的新球。

注意 \(i\geq j\)

AGC003

D (Medium)

非正解。

首先有個 \(O(nv^\frac{1}{3}+n\frac{\sqrt v}{\log v})\) 的做法,過不去。

然后換成 \(O(nv^\frac{1}{3}+nv^\frac{1}{4})\),就過去了。

你不想寫 pollard-rho,於是你發現兩個數都大於 \(\sqrt v\) 的匹配其實巨少,直接跑到 \(5\) 秒把剩下的都當沒匹配直接加進答案里就過了。

E (Medium)

首先離線一下操作,顯然如果兩個操作有 \(a_i\geq a_{i+1}\)\(a_i\) 就沒用了,於是我們可以把 \(a_i\) 轉成遞增的。

\(f(n)\) 為前 \(n\) 個元素的貢獻,顯然我們可以找到 \(<n\) 且最大的 \(a_i\),記這個東西的值為 \(x\),就可以將 \(f(n)\) 拆成若干個 \(f(x)\) 和一個 \(f(n\text{ mod }x)\) 了。

時間復雜度 \(O(n\log n)\),因為 \(\text{mod}\) 函數每次至少減半。

F (Hard)

因為題目是一個遞歸的形式,我們嘗試現在 \(2\) 層遞歸中找規律。

我們發現在兩個復制的交界處一定是上下交界或者左右交界。

於是考慮交界能否有交:顯然在原圖上有交的話,在每一層都會有交,反之亦然。

那么枚舉一些情況:

  • 上下左右都沒有交,顯然每次連通塊都一分為黑格數量個,答案為 \(cnt^{k-1}\),其中 \(cnt\) 為黑格數量。
  • 上下左右都有交,顯然每次遞歸完后都仍然聯通,答案為 \(1\)
  • 只有上下有交或只有左右有交,下面描述如何處理。

首先如果只有上下有交我們直接旋轉 \(90\) 度,這樣就只有左右有交了。

然后我們發現,在 \(2\) 層遞歸的圖中,只要原圖里有兩個相鄰的黑格,答案就會減 \(1\),初始答案為 \(cnt^2\)

類似地,我們只需要求出在 \(k\) 層遞歸圖中有多少相鄰的黑格就可以算了。

這是一個簡單的問題,直接矩陣快速冪就做完了。

AGC004

D (Easy)

注意到 \(1\) 必須是自環。

然后 \(1\) 肯定在基環樹上。

於是把 \(1\) 拆掉之后就是一棵樹了,隨便做。

E (Hard)

首先讓所有機器人移動的細節非常多,我們考慮只讓出口移動。

假設出口的移動范圍為一個矩形 \(\{i,j,k,l\}\)

這樣的話出口對應的矩形和原矩形就會有一個交,這個交外面的格子要么已經被收集了要么一定白給了,所以這個東西可以作為一個 dp 狀態。

我們設 \(f_{i,j,k,l}\) 為這個移動范圍下已經被收集或白給的格子中,最多被收集的數量,每次轉移即可。

F (Hard)

考慮樹的情況。

如果我們把奇數層的節點染黑,一次移動就等價於把兩個不同色相鄰節點翻轉,也就是移動一步黑色節點。

於是問題變成了奇數層有一些節點,每次可以移動一個,問多少次才能使所有白色節點變黑。

考慮每條邊的貢獻即可。

然后套一個環直接考慮斷環為鏈。

如果是偶環我們依舊枚舉某條邊貢獻,可以發現是一個經典模型。

最后說一下卡了我很久的奇環:這條邊的操作一定讓黑點 \(+2\) 或者 \(-2\),顯然黑白點相等后就不會再操作,所以直接加權值即可。

AGC005

D (Hard-)

考慮欽定 \(i\) 個點不合法,但是仍然滿足是一個排列的方案數。

我們發現給同行同列不合法的點連邊之后一定是若干條鏈,求鏈上獨立集。

於是就非常好做了。

E (Hard)

記先手在 A 樹上走,后手在 B 樹上走。

首先發現一個結論:如果存在兩個 A 樹上相鄰的點在 B 樹上的距離 \(\geq 3\),並且先手能走到那個節點,那么答案就是 \(-1\)

假設不存在上面那類邊,也就是說 A 樹的邊在 B 樹上的邊的長度 \(\leq 2\),這樣我們發現是必然走不出這個子樹的,直接 dfs 所有能走到的點,對答案取最大值即可。

F (Medium+)

考慮計算每個點算的次數,其實就是 \(\binom{n}{k}-\sum\limits_{i\in e_x}\binom{sz_i}{k}\)

於是我們只需要對 \(k=1,2,\cdots,n\) 求出 \(\sum\limits_{i=1}^nc_i\binom{i}{k}\) 即可,顯然 \(c_i\) 直接一遍 dfs 就可以求了。

於是推推式子:

\[\begin{align} f_i&=\sum_{j=i}c_j\binom{j}{i}\\ f_i&=\sum_{j=i}c_j\frac{j!}{i!(j-i)!}\\ i!f_i&=\sum_{j=i}c_jj!\frac{1}{(j-i)!}\\ A_{i}&=\sum B_{j}\times C_{j-i}\\ A'_{n-i}&=\sum B'_{n-j}\times C_{j-i}\\ \end{align} \]

就做完了。

AGC006

C (Easy)

不難發現只需要維護坐標期望即可,真實坐標沒啥用。

然后坐標期望是非常好算的,我們可以獲得一個 \(O(nm)\) 做法。

然后發現 \(n\) 次操作后相當於期望值乘上了一個排列。

於是直接倍增即可,時間復雜度 \(O(n\log m)\)

D (Medium)

首先二分。

二分完之后,我們發現如果有兩個相鄰數都是 \(1\)\(0\) 的,它們一定能一起上升到上一行。

於是求出包含中間的一段最小穩定段分類討論即可。

E (Medium)

首先可以把每一列抽象成它最后的位置和它當前的正反。

一次操作可以看成交換 \(a_x\)\(a_{x+2}\),並將 \(a_x,a_{x+1},a_{x+2}\) 都反過來。

於是我們求出奇偶數位置的逆序對數和初始狀態中被反過來的對數。

確認奇偶性即可。

F (Medium+)

這個題看起來巨大像圖論題,我們考慮轉化成圖論,也就是對於任意黑格 \((x,y)\),從 \(x\)\(y\) 連有向邊。

如果 \((x,y)\) 變黑了,那么一定存在 \((y,a),(a,x)\) 使得它們都是黑的,於是我們可以把一條正向邊轉化成兩條反向邊,又可以把一條反向邊轉化成兩條正向邊。

這樣可以怎么建模呢?我們考慮把正向邊看作 \(+1\),反向邊看作 \(-1\),這樣模 \(3\) 意義下就對了。

現在我們把邊拆成 \(+1\)\(-1\) 的兩條,要求任意兩個點是否可以走 \(sum\)\(3\) 等於 \(1\) 的邊到達。

注意如果邊都是一個集合連另一個集合是不可能生成新的邊的,要判掉。

AGC007

C (Hard-)

你需要觀察到一點:在推掉其中一個球之后,剩下球和盒子的距離的期望仍然是等差數列!

於是就做完了。

這也太神仙了吧?

D (Easy+)

最后方案一定是割成若干段,每次先走到一段的最右邊,再走回最左邊,再走到最右邊。

然后直接優化一下決策點記錄一下歷史狀態就好了。

注意一些很小的細節。

E (Medium+)

首先我們發現是求一個 dfs 序。

如果確定好 dfs 序之后怎么做呢?

我們可以用一個 dp 統計答案:\(f_i=\max(f_l,f_r,g_{l,1}+g_{r,0}),g_i=(g_{l,0}+w_l,g_{r,1}+w_r)\)

時間復雜度非常劣,但是我們發現這個東西完全可以二分。

二分之后我們相當於維護了一個合法的集合,去掉被二維偏序的點之后還剩一些較小值遞增較大值遞減的狀態。

這個時候我們發現,合並的時候就可以直接啟發式了!我們對於 size 較小的去搞一下,然后證明一下總狀態數並不會太多就行。

F (Hard-)

考慮答案一定是選一些字符,這些字符不斷向右延伸,出現沖突就新開一列。

我們可以發現它們盡量向右擠是最優的。

於是直接把匹配的位置算出來求每一列會有幾次沖突即可。

AGC008

D (Easy)

按照 \((a_i,i)\) 排序,然后每次將最前面有空的數用來墊着。

全部弄完之后再對於剩下的元素做一遍,每次也將最前面有空的數拿來墊着。

最后檢查一遍是否合法即可。

E (Medium+)

首先我們把 \(i\to a_i\) 表示成 \(i\)\(a_i\) 連邊,形成內向基環森林。

於是構造的排列就必須保證 \(i\)\(a_i\) 的距離 \(\leq 2\) 了。

稍微手玩一下可以得到結論:

  • 一個不是自環的連通塊一定最后還在一個環中。

  • 一棵內向基環樹可以分兩種情況:只有環,和有環上的點。

  • 兩個長度相等的環可以結合在一起。

  • 一個長度為奇數的環可以自己反一下。

  • 一棵內向基環樹如果不是一個環,不能和其它樹合並。

於是問題變成了兩個子問題:

  • \(n\) 個點,兩個點可以套在一起,有 \(k\) 種方法。
  • \(n\) 條線段,每條線段可以選擇覆蓋 \([i,r]\) 或者 \([(i+1)\%n,(r+1)\%n]\),問方法數。

好像都很水,於是就做完了。

F (Hard)

首先我們知道答案肯定不是每個點最大擴展次數的和,因為會算重

我們考慮所有算重的方案,顯然會存在一個 \(d\) 最小的(也就是說 \(d\) 相同,\(x\) 不同所構成的點集也一定不同),我們就考慮只對於這樣的 \((x,d)\) 計數。

然后我們考慮判定一組 \((x,d)\) 是否合法:對於所有和 \(x\) 相鄰的節點 \(y\),如果 \((x,d)\)\((y,d-1)\) 相等,那么 \((x,d)\) 不合法,反之合法。

也就是說,合法當且僅當去掉任意一棵子樹后,都存在一棵子樹的深度 \(\geq d\),即第二深的子樹深度 \(\geq d\)

特別地,覆蓋整棵樹可能不滿足上面的規律,所以我們不統計整棵樹對應的點集,在最后 \(+1\) 即可。

於是你把其中的一個 subtask 做完了,接下來考慮只能選其中部分點的情況。

那么其實也就是每個點多了一個下界,重點在於怎么計算這個下界。考慮用別的點替代一定是在某一棵子樹里選一個點,然后把這個子樹全選完,因此考慮所有有可以選的點的子樹,取最小的深度即可得到下界。

AGC009

C (Easy)

考慮平方 dp:\(a_{i}\) 屬於集合 \(A/B\),上一個屬於另一個集合的是 \(a_j\)

於是 \(f_{i+1,i,A}\) 等於一段區間的 \(f_{i,j,B}\) 的和,暴力計算這段區間即可。

注意有些時候因為 \(a_{i+1}-a_i<A\) 一個前綴都會變成 \(0\),需要處理一下。

D (Hard)

就是點分治,問分治最少層數。

我們發現答案顯然 \(\leq \log n\),考慮 \(O(n\log n)\) 的 dp。

考慮點分樹的一個描述:點分樹上深度相同的點的路徑肯定經過一個深度更小的點。

這個描述非常友好:我們發現如果我們將一些點的深度 \(+1\),這一點仍然滿足。

於是我們依次枚舉並判斷即可。

E (Medium)

首先我們考慮每個數對答案的貢獻,就是 \(a_i\times\frac{1}{k}^{t_i}\),其中 \(t_i\) 是這個數被操作的次數。

我們發現一個事實:我們可以構造出任意一組 \(\sum \frac{1}{k}^{t_i}=1\) 對應的操作序列!

於是問題變為了找若干個符合要求的小數,直接 dp 即可。

感覺這題反而沒有 D 難,為啥洛谷上是黑的啊。

AGC010

D (Easy)

對於 \(n\leq 2\) 特判。

然后你發現如果在不能改變數的奇偶性的情況下答案和所有數減 \(1\) 的和的奇偶性有關。

也就是說一個人如果發現他要輸了,必須想個辦法使得 \(\gcd\) 是偶數,即所有數都是偶數。

這顯然等價於場上只剩下一個 \(>1\) 的奇數且沒有 \(1\),此時他的操作也唯一,因此世界線收束。

迭代不會超過 \(\log n\) 輪,因此時間復雜度 \(O(n\log n\log a)\)

E (Hard)

顯然如果兩個數不互質那么它們的相對位置就固定了。

首先我們考慮先手確定了這張圖。

那么后手只要不斷取出 \(deg=0\) 的點中編號最大的點即可。

於是先手反過來使得每個連通塊這么做的字典序最小就是最優解。

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

F (Medium+)

現在假設先手從 \(1\) 挪到 \(x\)。如果后手在 \(x\) 這棵子樹必敗,那么它走回去之后先手可以再挪回來,因此后手必敗。

唯一的問題是如果 \(a_1\leq a_x\),會出現 \(1\) 先變不合法的情況,此時不能走這個分支,而其它情況都是可以的。

於是我們成功地把判斷一個點是否必敗分解到它的子樹是否必敗,對於每個節點 dfs 計算一次即可。

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

AGC011

D (Easy+)

手玩一下發現如果第一個牆激活了就會直接被彈回來,不然就可以走到第二個牆的右邊,此時第二個牆又被激活,不斷重復后就走到了另一側。

然后對於走到另一側的情況,對於每個牆,如果下一個牆一開始是激活的那么這個牆一定變成非激活,如果下一個牆一開始是非激活的那么這個牆一定被激活,而最后一個牆一定被激活。

也就是說我們要執行這樣的操作:循環右移一位並取反所有數,將開頭的 \(1\) 變成 \(0\)

不難發現這個操作一定以 \(2n\) 為循環節,直接暴力 \(O(n)\) 做就行了。

注意 \(k<2n\) 的步不一定在循環里,需要暴力做。

E (Medium)

可以發現其實一個上升數就是九個形如 \(111\cdots1\) 的數的和。

然而 \(111\cdots 1\) 並沒有什么優美的形式,我們考慮整體乘 \(9\)

於是一個上升數就是九個形如 \(10^x-1\) 的數的和。

也就是說, 我們要求出 \(x\) 至少要表示成多少個形如 \(10^x-1\) 的數的和。

注意到這個答案一定不會很大(最多為 \(9\log x\))我們可以直接從小到大枚舉並判斷。

於是我們只要支持高精度位數和和加 \(1\) 即可,時間復雜度 \(O(n\log x)\)

F (Hard+)

照抄 command_block 了,因為實在太過神仙。

顯然因為 \(k\) 個時刻會發一輛新車,所以所有車通過軌道的時間都可以對 \(k\) 取模。

\(p_i\) 為向右的車在 \(i\) 停靠的時間,\(q_i\) 為向左的車在 \(i\) 停靠的時間。

我們可以列出從左向右的車通過第 \(x\) 個區間的時間為 \(\sum\limits_{i=1}^{x-1}a_i+\sum\limits_{i=0}^{x-1}p_i\sim\sum\limits_{i=1}^{x}a_i+\sum\limits_{i=0}^{x-1}p_i\),而從右向左的車通過第 \(x\) 個區間的時間為 \(-\sum\limits_{i=1}^{x}a_i-\sum\limits_{i=0}^{x-1}q_i\sim-\sum\limits_{i=1}^{x-1}a_i-\sum\limits_{i=0}^{x-1}q_i\)

如果我們設計的方案合法的話,這個區間是不會有交集的,也就是說這兩個集合的交集應該是空的。

稍微整理一下可以得到一個優美的式子:\(\sum\limits_{i=0}^{x-1}p_i+q_i\notin(-2\sum\limits_{i=1}^{x-1}a_i,-2\sum\limits_{i=1}^{x}a_i)\)

做到這個形式之后就非常簡單了,每次把這段區間的數放到右邊就可以了,可以直接線段樹維護 dp。

感覺這題非常困難……准備給后面更困難的題開新等級了。

AGC012

C (Easy)

我們發現如果我們能欽定后一半,那么數量可以轉化為前一半符合某種條件的子序列數。

注意到字符集很大,我們嘗試構造一個排列。

我們先輸出這個排列,再輸出一個 \(1\sim n\) 的排列,那么答案就轉化為了長度為 \(n\) 的上升子序列數量。

直接倍增構造答案即可。

D (Medium)

考慮這個交換和這個數在哪個位置根本沒有關系。

於是如果 \(x,y\) 可以交換,\(y,z\) 可以交換,那么 \(x,y\) 也可以交換,因此我們就可以划分出若干個可以交換的集合,對於每個集合求階乘即可。

對於每種顏色,同色交換事實上就等價於有一部分數能和 \(w\) 最小的數交換,異色交換就等價於其中一種顏色 \(w\) 最小的能和另一種顏色的一些球交換。

於是剩下的部分是非常平凡的,求出每種顏色內部的集合和顏色之間的連邊即可。

E (Medium)

如果你做不出來,一個提示:\(V\) 的值域只有 \(2\times 10^5\)

不難發現 \(\log V\) 次跳躍之后 \(V\) 一定變為 \(0\),每次跳躍之后能走的都是一個區間。

然后我們就把 \(\frac{1}{2}V,\frac{1}{4}V,\cdots,1\) 分給左邊的前綴和右邊的后綴,如果存在一種分法就是 possible。

顯然我們可以算出使用集合 \(s\) 時最長能覆蓋多長的前綴/后綴,唯一的問題是,如果我們對於每個點暴力 check,時間復雜度是 \(O(nV)\) 的。

事實上對於每個長度為 \(V\) 的極長區間的答案都是一樣的,而如果極長區間的數量超過了集合中數的數量一定無解,因此時間復雜度降低到 \(O(V\log^2V)\),可以通過。

F (Hard+)

首先我們知道 \(a_i\leq b_i\leq a_{N-i}\)

\(b_i=x\),然后我們知道每次如果我們加兩個小於 \(x\) 的數 \(x\) 就會變成 \(x\) 的前驅,加兩個大於 \(x\) 的數 \(x\) 就會變成 \(x\) 的后繼。

注意到一個數和前后綴之間一定不會相隔其它的數,所以對於任意 \(i>j\),肯定不存在 \(b_i<b_j<b_{i+1}\)

在這基礎上,我們可以證明以上兩個條件已經充分,從后往前構造序列即可。

於是在這個結論下,我們可以設計一個從后往前的 dp:\(f_{i,j,k}\) 代表要選 \(i\) 位,前面還有 \(j\) 個數可選,后面還有 \(k\) 個數可選的方案數。

轉移是平凡的,時間復雜度 \(O(n^4)\)

AGC013

D (Easy+)

我們可以把放進去一個紅球,拿出來一個藍球改成放進去一個指定球。

於是我們考慮轉化成現在只有 \(n-1\) 個球,做 \(m\) 個放球,拿球的循環(如果先拿球可能存在一些特殊的 case),最后答案乘以 \(2\)

這樣就等價於你可以做 \(m\)\(\pm1,0\) 的操作之后求極差 \(\leq k\) 的操作序列數量。

這個題就比較平凡,先枚舉極小值,然后因為 \(n,m\leq 3000\) 的特性直接暴力 dp 轉移即可。

E (Easy+)

首先這個 \(\prod a_i^2\) 看起來非常陰間,我們直接大力組合意義拆成在區間里選一個點打一種標記,再選一個點打另一種標記。然后這一切就都好起來了!

\(f_{i,0/1,0/1}\) 表示放完前 \(i\) 個,是否打第一種標記,是否打第二種標記,非常好寫出轉移。

然后如果某個位置被禁了,就代表不能在這個位置新開一段,因為只有 \(10^5\) 個位置,我們直接暴力轉移。

時間復雜度 \(O(m\log n)\),常數應該比較大。

F (Hard+)

首先我們都知道對於兩個已經確定的序列,只需要檢驗對於任意一個值 \(v\)\(a\) 序列中 \(\leq v\) 的數的數量都多於 \(b\) 序列中 \(\leq v\) 的數的數量。

於是我們直接轉化,就變成了有一個序列和若干區間,每次給一個后綴臨時 \(+1\),問至少要選擇多少區間 \(+1\) 才能使得每個數 \(\geq 0\)

我們考慮有沒有不依賴於后綴的決策:顯然對於一個 \(\leq -2\)\(v\) ,它必須被覆蓋到至少 \(-1\)

然后最后相當於我們只需要覆蓋一段前綴的 \(-1\),我們可以對於每個前綴分別求出答案。

特別注意的是,第一遍我們應該從后往前依次處理,不然如果 \(4\) 需要一個區間,我們選了 \([2,6]\),但是如果覆蓋了 \(2\) 開始的后綴,最優的方案應該是選 \([1,5]\),這個貪心就錯誤了。

AGC014

D (Easy)

如果一個點有兩個葉子顯然木大。

如果一個點有一個葉子顯然可以把這個點先選強迫后手選那個葉子,這樣就可能產生更多葉子。

直接選擇一個非葉子節點 dfs 模擬即可。

E (Easy)

注意最后一次連邊,一定是直接一條藍邊換一條紅邊。

而這次連邊之前,顯然這條邊一定要被保留,所以直接將這兩個點合並即可。

代碼有一些小細節。

F (Hard)

對於 \(i=1\),顯然這個數不會影響別的數是不是前綴最大值。

於是其實我們先求出 \(i=2\sim n\) 的答案,然后再看看這么多次之后是否 \(1\) 也歸位了。

顯然在 \(i=2\sim n\) 的倒數第二步完成時,此時 \(2\sim n\) 的第一個數顯然不是 \(2\)

我們考慮將第一個數 \(x\)\(1,2\) 的位置關系求出,然后證明一個非常厲害的事情:這三個數相對的循環順序不會改變。

具體證明基於一個結論: \(x\) 當且僅當在第一個位置時是前綴最大值,其它情況都不是前綴最大值。

於是在最后一步完成時,如果我們在所有操作前的相對順序是 \(1,2,f\),那么 \(1\) 就自動歸位了。不然第一位上的數還是 \(2\),就需要再合並一次。

直接模擬這個過程掃一遍就行了。

AGC015

D (Easy)

考慮不斷求包含最高位的數有多少能被表示。

假設現在同時存在有最高位的數和沒最高位的數。

不含最高位的數能構造的數顯然在 \([l, 2^x)\)

包含最高位的數構造的數顯然在 \([2^x,2^{x}\text{ or }(2^{x}+1)\text{ or }\cdots\text{ or }r)\)

將它們的並集加入答案,並將最高位的數都丟了,分解成子任務。

如果所有數的最高位相同,顯然所有能構造的數都包含最高位,減去最高位后分解成子任務即可。

時間復雜度 \(\text{polylog}(r)\)

E (Medium-)

注意所有點最后一定按照 \(v\) 排序。

對於第 \(i\) 個點,如果有第 \(j\) 個點最開始在 \(i\) 后面,最后在 \(i\) 前面,那么 \([i,j]\) 的所有點顯然都在 \(i\) 被初始染色的時候染上色。

於是我們可以算出第 \(i\) 個點的染色區間 \([l,r]\),顯然 \([l,r]\) 有單調性,隨便 dp 一下就可以了。

F (Hard)

我們要構造答案越大越好,注意到如果 \(x<y\)\((x,y)\) 會變成 \((y\bmod x,x)\),我們直接反向構造,從 \((0,1)\) 開始反推。因為我們要讓用的數盡可能小,我們顯然會從 \((y,x)\) 推回 \((x+y,x)\)

最后會發現其實最小的最深答案就形如 \((Fib_i,Fib_{i+1})\),因此答案也只有 \(\log n\) 級別。

考慮哪些數對可能可以這樣反向構造回去。顯然構造的方法就是不斷推回 \((kx+y,x)\)

不難發現 \(k\) 在除了最后一步的位置只能取 \(1\)\(2\),不然可以證明如果這樣存在解則存在一個答案更大的解。同樣不難發現的是 \(2\) 只能選一次,證明的方法是類似的。

因此我們還證明了除去最后一層,反向構造在最后一步之前只能構造出層數個解。

於是我們直接對於所有解求出最后一步能得到幾個合法對即可。

注意在只有一層的時候特判。

AGC016

D (Not solved)

我們記所有數的異或和為 \(S\),顯然每次的操作就是交換 \(a_i\)\(S\)

我們考慮對於所有 \(a_i\neq b_i\)\((a_i,b_i)\) 連邊,對於每條邊答案 \(+1\),每個連通塊答案 \(+1\)

最后注意如果存在 \(b_x=\bigoplus\limits_{i=1}^n a_i\),可以省去一次。

E (Medium-)

每只雞的情況要么是一定死,要么是可能活下來。

如果一只雞可能活下來,那么一定存在一個集合 \(S\),只有集合 \(S\) 中的雞全在某次選擇中被獻祭才可能讓最后的某只雞活下來。

我們可以依次模擬所有操作,如果某次操作為兩只都有可能存活的雞 \((x,y)\),那么 \(y\) 的集合就要或上 \(x\) 的集合,並且 \(x\) 的集合也要並上 \(y\) 的集合。

特別地,如果兩個集合交集為空,顯然這兩只雞都必死,因為一只雞沒有辦法獻祭兩次。

最后枚舉集合判斷交集是否為空即可,時間復雜度 \(O(n^3+nm)\)

F (Medium)

不難扯到 SG 函數上做。

我們考慮直接欽定每個點的 SG 函數,然后要滿足以下要求:

  • \(sg_i=A\) 的點要對於每個 \(B<A\) 向至少一條 \(sg_j=B\) 的點連邊。
  • \(sg_i=A\) 的點之間不能連邊。

那么我們考慮欽定一個點集是合法的,每次加一個新的點集,加入的點集的 SG 函數都是原點集的 SG 函數最大值 \(+1\)

再看看要滿足什么要求:這些點之間的邊全部不取,對於每個集合外的點和新選的點之間的連邊要至少選一條邊。

可以做到 \(O(n3^n)\)

AGC017

D (Easy)

經典 SG 函數練習題。

我們嘗試表示一棵子樹的 SG 函數。

不難發現,如果加入一棵子樹,因為子樹可以變成任意操作后狀態或者直接消失,所以相當於 SG 函數異或上 \(f_y+1\)

檢查 \(f_1\) 是否為 \(0\) 即可。

E (Medium)

講個笑話,我一直以為可以翻轉。

記一個點某側的權值,接地為 \(-a_i\)\(b_i\),沒接地為 \(c_i\)\(-d_i\), 顯然兩個點能連當且僅當權值相等。

於是大力邊轉點,我們就要從一個正數點開始,走若干個有向邊到負數點。

注意到可以不連成一段,所以可能會走多次。我們建一個超級起點和超級終點,檢查是否在增加若干條這兩個點之間的邊后存在一條歐拉回路即可。

具體來說就是每個正數點出度都不比入度少,負數點同理,並且不能有一個連通塊內部消化完了。

F (Medium+)

顯然的思路:放完 \(x\) 根線,狀態為 \(S\) 的方案數,時間復雜度高達 \(O(4^{n}\text{poly}(nm))\)

問題在於我們一次枚舉了過多的狀態,我們嘗試分解每層的狀態。

考慮放完 \(x\) 根線,第 \(x+1\) 根線覆蓋部分方案為 \(A\),未覆蓋部分方案為 \(B\),兩個狀態之間距離為 \(d\)

時間復雜度為 \(O(2^nn^2m)\),空間復雜度 \(O(2^nn)\),無法通過。

我們發現覆蓋的特殊要求就是 \(A\) 的前綴 \(\text{popcount}\) 要大於等於 \(B\) 的前綴 \(\text{popcount}\)

所以可以不記錄到某一位的距離,記錄第 \(i\) 條線走完前 \(j\) 步,已經覆蓋的位為 \(A\),剩余要覆蓋的位為 \(B\) 的方案數即可。

AGC018

D (Easy+)

首先對於哈密頓回路的問題是經典的,就是每條邊的邊權乘 \(\min(sz_x,sz_y)\)

對於哈密頓路,顯然我們只需要扣掉一條邊。

我們考慮哈密頓回路的構造方式,核心就是要每次進入以重心為根的不同子樹。

因此我們扣掉一個點只需要扣掉最后回重心的那個點即可,答案只需減去重心的出邊中距離最短的那條。

特別注意的是如果有兩個重心,那么只有它們之間的邊是兩個重心的公共出邊,特判即可。

E (Not solved)

F (Not solved)

AGC019

D (Not solved)

E (Not solved)

F (Hard-)

顯然如果還剩 Yes 多我們就猜 Yes,不然猜 No。

於是我們放到二維平面上,每個決策可以表示成一條邊,數所有路徑經過的決策邊數量之和即可。

唯一的問題是決策邊的數量並不好數,是這個形狀的:

我們考慮把每條邊超出斜線的部分強行折回去,然后加上 \(0.5\) 的貢獻(因為一定會走一條超出斜線的豎邊)。

計算斜線上的每個點被經過的路徑條數即可。特別注意因為事實上我們沒有折回去,所以計算的其實就是走到左下的路徑數量乘以走到右上的路徑數量。

AGC020

D (Not solved)

E (Not solved)

F (Not solved)

AGC025

D (Easy+)

對於所有距離為 \(D_1\) 的點連邊,可以證明這是一張二分圖。

取出點較多的一側,對於所有距離為 \(D_2\) 的點連邊,仍然可以證明這是一張二分圖。

因此最終至少可以選出 \(\lceil\frac{\lceil\frac{4n^2}{2}\rceil}{2}\rceil\geq n\) 個點。

E (Hard)

拋出一個結論:所有被經過至少兩次的邊都能提供 \(2\) 的貢獻。

考慮每次選一個葉子。

如果這個葉子沒有連向父親的路徑,那么我們什么都不用考慮,直接刪點即可。

如果只有一條連向父親的路徑,我們就之后再考慮,將這條路徑的起點改為它的父親。

如果有 \(\geq 2\) 條連向父親的路徑,我們選一條定一個方向,再選一條定反方向,剩下的隨意。

設這兩條路徑的終點分別為 \(a,b\),它們從當前結點 \(x\) 分開的位置為 \(t\),顯然 \(x\to t\) 的路徑肯定被覆蓋兩次,而 \(t\to a\)\(t\to b\) 因為方向相反可以變成 \(a\to b\) 的路徑。顯然因為這個節點是葉子,\(x\) 肯定不等於 \(t\),所以我們成功地將問題縮小到了相同條件的更小規模,反復操作即可。

由於數據范圍很小某些地方可以復雜度換碼量,然而細節還是很多。

F (Hard-)

每次操作可以看成是從高到低,對於每個都為 \(1\) 的位產生一次進位,並處理隨之帶來的進位。

我們發現一件神奇的事情:我們可以對於從高到低的位,直接產生至多 \(k\) 次進位,與上述操作等價。

證明可以使用歸納法,在我們增加一次的時候,如果某一位上都是 \(1\), 那么這一位進位之后位置上的數一定是 \(0\)。而即使它下面的所有位都全為 \(1\),這一位也無法繼續進位。

此時我們得到了一個 \(O(nk)\) 的暴力,考慮繼續優化。

我們發現只有在 \((01,01)\) 的情況下對低位進位不會減小 \(0\) 的個數,於是我們將連續的 \((0,0)\) 段壓在一起存之后暴力模擬,時間復雜度即為 \(O(n)\)

有趣的事實:zhoukangyang 沒有使用這個性質也切掉了此題,大家可以膜拜他。

AGC055

A (Easy+)

我覺得比 B 難。

將字符串分成三段,每次枚舉一個 ABC 的排列 \(s\),嘗試在第 \(i\) 段中找出盡可能多的 \(s_i\),取最小之后將這些字符取出即可。

可以通過一些方式證明最后一定能取完。

B (Easy)

首先我們發現無論怎么操作每種字符的數量都是不變的。

注意到一個性質:如果有一個 ABC,它可以和任意一個字符交換。

於是我們直接對於 \(s,t\) 尋找 ABC 並移到最前面即可。

當沒有東西可以移動時能否轉換等價於剩下的兩個串是否完全相同

C (Medium-)

一個顯然的性質:所有數的答案要么是 \(L-1\),要么是 \(L\),其中 \(L\) 為序列的 LIS 長度。

於是一個很自然的想法是枚舉哪些位置是 \(L-1\)

枚舉完哪些位置是 \(L-1\) 之后,我們發現我們要求的就是 \(L\) 的最大值和最小值。

最小值是顯然的,也就是 \(L-1\) 的位置數量,構造為剩下的數全選 \(+\infty\),注意要和 \(3\)\(\max\)

最大值應該是在每個空隙中盡可能塞若干對數。

例如,我們選擇 \(\{1,3,6,8\}\),那么我們可以讓 \(a_3<a_4=a_5<a_6\),那么這樣 LIS 長度就增加了 \(1\),注意 \(0\)\(n+1\) 都必須選上。

不難發現能塞的對數和選的數的數量只和長度為奇數的空隙有關,枚舉選的數的數量和長度為奇數的空隙計算即可。

注意選所有數和不選數是兩種情況。

D (Hard)

神仙結論題。

\(A_x\) 為序列所有前綴 \(A\)\(B\) 多的數量的最大值,\(B_x\)\(C_x\) 的定義類似。

拋出一個神仙結論:序列可以被分解當且僅當 \(A_x+B_x+C_x\leq n\)\(A,B,C\) 各有 \(n\) 個。

必要性顯然,充分性也可以通過一些技巧證明。

於是直接大力 dp 就可以了。

E (Not solved)

F (Not solved)


免責聲明!

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



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