連結1
連結2

題解

首先轉換題目如下:

給定序列 a1,a2,,ana_1,a_2,\dots,a_nb1,b2,,bkb_1,b_2,\dots,b_k ,對於 aa 序列,定義一個區間的分數 cost([l,r))=al,al+1,,ar1,b1,b2,,bk\text{cost}([l,r))=a_l,a_{l+1},\dots,a_{r-1},b_1,b_2,\dots,b_k 中前 rlr-l 大元素的和。求出最大分數。

可以驗證 cost\text{cost} 符合 Monge condition ,那用來解決此問題的演算法就多了,於是可以先想 cost\text{cost} 要怎麼很快的算出來。
最簡單的方法當然就是持久化線段樹算前 rlr-l 大,每次操作時間複雜度是 O(log(n+k))\mathcal{O}(\log (n+k)) ,而且可以隨機存取式的隨意算cost,這樣就可以使用 SMAWK 演算法在 O(nlog(n+k))\mathcal{O}(n \log (n+k)) 的時間做完,但空間需要 O(nlogn)\mathcal{O}(n \log n) 。所以可以考慮使用 sliding window 算 cost ,會有非常大的可能可以把空間壓到線性。
但在使用 sliding window 算 cost 的時候,只能使用轉移點單調 (Monotone Minima) 或是簡易版 LARSCH ,兩者的時間複雜度皆為 O(f×nlogn)\mathcal{O}(f \times n \log n)ff 為 sliding window 移動一次和算答案的時間。因為這題 n106n \le 10^6 ,所以我們希望 f=O(1)f=\mathcal{O}(1)
如果存在一個 sliding window 能用 O(1)\mathcal{O}(1) 的時間加入元素以及計算答案,那就能在 O(n)\mathcal{O}(n) 的時間內解決 Maximum Gap\text{Maximum Gap} 問題,但此問題在 algebraic computation tree model 下有 Ω(nlogn)\Omega (n \log n) 的時間複雜度下界[1],所以加入元素的 sliding window 大概做不到 O(1)\mathcal{O}(1)

既然加入元素不行,那可以改成考慮刪除。先花 O((n+k)log(n+k))\mathcal{O}((n+k)\log(n+k)) 的時間將 aabb 的元素一起由大到小排成長度為 n+kn+k 的序列,將這個序列用 linked list 維護,因為 sliding window 在移動時 rlr-l 只會改變 11 ,所以可以做到 O(1)\mathcal{O}(1) 刪除,且刪除後新的前 rlr-l 大元素和也能在 O(1)\mathcal{O}(1) 維護。
轉移點單調和簡易版 LARSCH 的 sliding window 移動順序都支援使用只能刪除和回滾的 sliding window ,所以只須套用這兩個演算法其中之一就可以把此問題做到 O((n+k)log(n+k))\mathcal{O}((n+k) \log (n+k)) 時間 O(n+k)\mathcal{O}(n+k) 空間。

實作細節的部份,可以跟每個節點說遞迴離開的時候要把 sliding window 復原成遞迴進這個節點時的樣子,會好想以及好寫很多。

一些廢話

原本我是寫簡易版 LARSCH ,需要兩個 sliding window ,想實作加寫搞了三個小時(太笨想很久才想到上面提的實作細節),然後才發現其實可以轉移點單調。
寫這篇 blog 的時候我 hexo 的 mathjax 爛了,遂改用 katex 。
改完 katex 之後發現我的 footnote 爆了,所以就開始改改改改改,改到連 markdown 的 renderer 都換了。我花在修 blog 的時間都比我寫這題的扣的時間還要長==


  1. Lee, D. T., and Ying-Fung Wu. “Geometric complexity of some location problems.” Algorithmica 1.1 (1986): 193-211. ↩︎

前言

北市賽終於結束了,這幾個月負責校內賽和校隊培訓害我翹了好幾堂微積分,有夠忙的,終於可以休息了。

校內賽

校內賽出題主要是顏子喬在負責,題目也幾乎都是他出的。我今年沒進二階之後就開始頹廢了,而且也沒什麼好的題目idea。
顏子喬超怪,他測資檔案用1-based編號(TIOJ 是 0-based),然後範例測資放最後。
然後複賽的非典型是我架的,因為我很正常所以我測資檔案用0-based編號然後範例測資放最前面。
感謝8e7在IOIC出的two steps讓我有code可以抄。
在TIOJ寫special judge的時候,直接#include "testlib.h"然後用registerTestlibCmd(argc, argv);會爛掉,原因是TIOJ上argv的順序不一樣,解決方法是自己改順序或是用魔改過的testlib
顏子喬今年有找人驗初、複賽的題,結果真的驗出測資出錯😔
抱怨一下,為了驗題所以我需要把這些題目搬到其他judge上,而codeforces雖然沒有子題聯集和沒辦法出除了互動題的非典型以外也夠用了(其實是我只知道可以放到codeforces上),然後polygon設定子題超麻煩,要一個一個測資標記他是哪個子題的==

校內賽的結果其實讓我們有點意外,很多人不喜歡喇分,導致今年晉級線特低。

校內培訓

基本上就是拿著一年前的資讀簡報上課,然後我也順便複習。
有好幾堂培訓在禮拜二或禮拜四早上,上完之後還要趕去台大上微積分😔

模擬賽

我叫顏子喬去出2-SAT,因為之前IOIC的時候好像很多人不會2-SAT(這我QQ),所以我覺得要讓大家都好好學一下2-SAT。
我出了兩題,一題是模擬,光是要打那題的題面就花了我很多時間,因為我發現我不太會敘述,修了很久才修到比較順,但還是有點難讀。
那題的很麻煩的分段函數不是我自己算的,我直接把每個斷點丟給chatGPT,然後他就幫我算好了。
另一個很麻煩的點是這題要寫浮點數比對,但我之後發現我可以從polygon偷上面的浮點數checker,就輕鬆解決了。
我本來預期會有人看不懂那題,所以特地提醒看不懂可以發Q&A,但結果沒有人問。

我覺得我出的另一題還不錯,推薦大家去寫。在測的時候發現免費的chatGPT開thinking也做不出來我蠻爽的

北市賽

前一天我複習了蠻多圖論的演算法,但是發現我約瑟夫問題不好,有點緊張。
因為我去年破台,所以我今年目標也是破台。但我其實很怕我被梗題梗到,然後被肘飛,而且選訓被梗題肘飛的經驗讓我蠻怕我會因為這樣被肘出全國賽晉級名額😔

題目懶得放了,因為有些我忘記了。

總之以下是我賽中的想法。

反正順利進全國賽了,希望這一個月努力練習,全國賽可以拚到一等。

這次建中只有四個進全國賽,其中三個是高三,代表明年負責出校內賽的人只有一個人,好慘QQ

最後噴一下北市賽:題目品質有夠飄,題敘很難懂而且還有誤導,誰愛打誰打,反正今年是我最後一年了,不用管了🥳

12 / 6

因為13:40才要去建中集合,所以我就在家待到9點多才出門,然後在費曼耍廢三小時。
然後建中所有人只有我帶行李箱,因為我塞了一件羽絨外套在裡面,但其實也沒用到。

我們好像是比較晚到政大的,所以講堂裡面沒剩很多連續的座位,我看到尉崴旁邊有兩個空位,然後我就問詹哲崴要不要去坐尉崴旁邊。
然後就在講堂進行開幕式,聽了系統環境、競賽規則及注意事項說明,然後負責說明的教授講了一句怪話:「題目的子題採自動交集」。

然後就是測機時間,測機有三題,pA是他教你隨機,pB是互動提,pC是數獨output only。
我先寫了一下pA,然後去寫pC,因為全國模擬賽的測機題有一樣的題目,結果有一個測資我忘記怎麼寫了,沒拿到滿分。

測完機就搭車去飯店了。
分享一下,顏子喬擅長測機。
map_tle

到了飯店開始發房卡,我跟王以安住一間。發完房卡之後他就發餐盒,然後餐盒的意思其實是便當,蠻好笑的。
飯店的浴室有個窗戶,可以直接從床那邊看過去,但是有窗簾可以拉下來。
然後浴室沒有乾濕分離,只有浴缸然後沒有浴簾,洗澡的時候一開始我盡力不讓水噴出去,所以蹲著洗,結果好像怎麼搞都會噴,而且蹲著很累,我就放棄了。

晚上實作了去年全國賽的pE,大概半小時寫完(雖然之前就大概想過怎麼實作了),然後一發過,好爽。
大概22:30就有點想睡了,然後把東西弄一弄大概23:30才躺到床上睡覺。

12 / 7

睡得不錯。
然後就衝去吃早餐,我的策略是早餐吃多一點,然後比賽的時候不吃東西。

然後以下是大爆雷。

前情提要

雖然複賽打得有夠爛(rank 8),總之進校隊了。
從複賽到北市賽之前有差不多一個月的時間,在這期間我看了很多題,還有北市賽的考古題,然後學了一些字串演算法,還玩了一下Hopcroft Karp常數比較小的寫法(雖然他要shuffle但是真的很好玩)
北市賽前一周和顏巨砲和詹哲崴vir了BOI 19,然後d2心態炸了打爆炸爛,心態穩的話有機會打得更好。還好BOI 19 d2打太爛沒有影響到我打隔天北市模擬賽,拿了一個rank 2,好爽。
北市賽前兩天連上北市賽的CMS系統測試,然後他的judge只有C++17的選項,不知道在幹嘛。

北市賽當天

早上就先去報到然後聽個規則就準備開打了。

以下是題目:

pA

NN個物品(1N16)(1 \le N \le 16),和一個容量限制QQ,每個物品有pi,si,tip_i,s_i,t_i,要你把每個物品按照pip_i排序之後,把排序後的序列拆分,使得拆分後的每個區間的siQ\sum s_i \le Q,每個區間的cost是maxti\max t_i,求每個區間的cost和最小值。

pB

你有一個N×MN \times M大小的矩形(1N,M500)(1 \le N,M \le 500),還有KK種太陽能板(1K1000)(1 \le K \le 1000),第ii種太陽能板長hih_iwiw_i,每種都能無限用。你要把N×MN \times M大小的矩形分割,第一次分割可以任意分割,第二次以後只能在分割後的區域分割,並在分割後的區域裝上大小不大於此區域的太陽能板,第ii種太陽能板裝上去之後可以得到pip_i的收益,求收益最大值。

pC

求長度為N(1N109)N(1 \le N \le 10^9),由C,D,E,F,G,A,B\text{C,D,E,F,G,A,B}七種字母組成,且符合以下規則的字串有幾種。

  • D\text{D}之後不能放A\text{A},但是可以有DAD\text{DAD},且DA\text{DA}可以是最後兩個字母。
  • count(E)+count(G)\text{count(E)+count(G)}必須為偶數。

pD

給一個M(1M9×105)M(1 \le M \le 9 \times 10^5),和NN個物品(1N100)(1 \le N \le 100),每個物品有pi(1pi106)p_i(1 \le p_i \le 10^6),要你求出,所有物品的子集SS使得iSpiM\sum_{i \in S} p_i \ge M(iSpi)M(\sum_{i \in S} p_i) -M的最小值。

pE

給你一個只有加法的運算式,加號數量最多10510^5,每個數字用一個大寫英文字母代表,之後給你每個加號的執行順序,要你加上括號讓這條運算式加號的順序和他給你的順序一樣。
例如運算式是A+B+C+D,順序是2 3 1,那輸出要是(A+((B+C)+D))

pF

MM個山峰(1M2×105)(1 \le M \le 2 \times 10^5),每個山峰有位置pip_i和高度hih_i,保證所有人的pip_i相異。然後有NN筆詢問(1N50000)(1 \le N \le 50000),每次詢問給KK個人的起始山峰(K2×106)(\sum K \le 2 \times 10^6),每個人都只能走到高度不低於他的山峰,而這KK個人要走到同一個山峰去開會,從ii山峰移動到jj山峰的移動距離是pipj|p_i-p_j|,求每個人移動距離和的最小值。

感想

比賽規則講的C++14和兩分鐘上傳間隔都是假的,有夠好笑,看到CMS上有C++17我就爽爽開用了,不過兩分鐘上傳間隔可能是因為傳上去之後要跑兩分鐘以上,然後你就真的可以等兩分鐘。

然後聽說有些人pD爆搜+剪枝拿100分,北市賽很會生測資。

負責北市賽的教授說他們預期一等獎的人都可以破台,什麼鬼。而且這場北市賽有4題dp,連一題圖論都沒有,本來我考前猜會考DAG最小路徑覆蓋和高斯消,結果這場有夠簡單==

總之有TIOJ管理員了,然後要負責出明年的校內賽。然後我希望我全國賽打好一點,我不想打TOI初選。

連結

可以列出dpi,j=uSdpi1,u\text{dp}_{i,j}=\sum_{u \in S}\text{dp}_{i-1,u},其中SS是有邊uju \to j的所有uu的集合。
這樣轉移的複雜度會是O((N+M)K)O((N+M)K),不會過。
觀察到題目給的圖是一個大環加一些邊,而且環以外的邊數MM很少。
而且用大環轉移其實就是把整個陣列往右cyclic shift一位。
所以可以先轉移大環,再把MM條額外的邊的轉移補上。

連結

如果只利用「目前最大值」對逆序數對的貢獻,原題可以轉化成 : 在00n1n-1裡面挑一些數使得他們的和=k=k,可以用數歸證明一定可以達成,而構造這個問題的解只需要貪心的由大的往小的選就好了。
再轉回原題,可以利用「目前最大值」選一個數;用「目前最小值」跳過一個數。

TESTEEEEE

H1個一個

H2

H3

H4

H5

8

OWOOVO\color{black}{\text{O}}\color{red}{\text{WOOVO}} the coding pooh\color{black}{\text{t}}\color{red}{\text{he coding pooh}}

超連結

你是一個一個一個[1]

danger

warning

info

success

struct GPOW {};

template <unsigned N>
struct owoovo {
    owoovo<N - 1> 巨炮;
    GPOW 巨砲;
};

  1. 施竣耀 ↩︎

0%