SSL-OI夏日合宿 2020.08.17 A組
SSL-OI夏日合宿 2020.08.17 A組
今天是他的生日,讓我們祝他生日快樂!
這套題是北大爺不知道從哪裡找來的, 只知道出題人署名是 HR今天也是卑微爆0, 下次一定(?)認真打簡單題&暴力
部落格好久沒更了, 主要是因為腐太多了? 還是要好好打一打題解的, 不然真的啥都沒留下就退役了.
今天的程式碼估計要咕, 還是先打完部落格梳理一下思路吧.
T1 圖
題意
給一個n個點n條邊的圖, 邊權表示所連的兩點的權值和. 給出邊權, 求點權.
正解
顯然這是一棵基環樹, 圖中的環是一個\(k\)元一次方程組, 可以求解. 環上的點權解出後, 對於每棵樹上的點權直接求出.
有關x元一次方程組的求解, 可以用高斯消元, 但在這道題中有更加簡單的解法: 考慮到每個方程組只有兩個非\({0}\)
T2 上升子序列
題意
給出一個數組, 要求將其分為兩個上升子序列, 求兩個子序列的差最小.(無解輸出\({-1}\))
正解
考慮到每一個值都必須在某個上升子序列中, 那麼對於每個逆序對, 都必在兩個不同的上升子序列中. 所以對於每個逆序對, 我們連一條邊, 然後跑二分圖染色. 若染色不成功, 則陣列不合法. 若染色成功, 圖中會剩下x個連通塊.
證明
對於每個連通塊,會有一個固定的長度差. 得到每個連通塊的差值後, 要使總差值最小, 只要DP每個數取\({+}\)或取\({-}\).
T3 大冰隙2
題意
給出一個序列, 每個元素\(i\)包含兩個值: 種類 \({b_i\in\{0,1\}}\) , 數值 \({c_i<2^{30}}\).
支援兩個操作:
修改: 單點修改某個元素的數值.
查詢: 相鄰兩個種類為的元素會被消去(不計入答案), 某一段消去後其左右兩邊視為相鄰. 求一段區間中沒被消去的元素的最大數值. (無剩餘輸出 )
思路 (故事)
暴力的日子就要用暴力的解法.很顯然這題是一個區間查詢問題, 那麼我們用莫隊; 這題有修改, 那麼我們用帶修莫隊; 這題合併不可逆, 那麼我們用回滾莫隊. 另外還要維護一棵平衡樹(multiset)支援插入刪除求最大.
綜上: 這題可以用帶修回滾莫\({N\sqrt{N}\log_2{N}}\)的複雜度獲得?分的好成績. (正常都是因為沒打出來而爆0吧?)
正解1 樹剖
我們發現有順序的\({01}\)抵消很像出入棧順序, 我們把一段\({01}\)序列視作某棵樹的dfs序的一部分, \({0}\)表示向下遍歷, \({1}\)表示向上回溯.
注意: 若有"多餘"的\({1}\)則新建一個點作為新的根, 將舊的根作為其兒子.
如此建樹後, 每棵棵子樹內的所有點都沒有貢獻, 區間查詢問題變成了樹上兩點間的路徑最大值查詢, 我們用樹鏈剖分即可.
注意: 由於邊權有向的, 設\(x<y\)有: 鏈 \({x}\)->\({LCA(x,y)}\)應取向上邊權, 鏈 \({y}\)->\({LCA(x,y)}\)應取向下邊權. 我們開兩棵線段樹分別處理向上/向下邊權即可.
正解2 樹套樹
顯然對於某段區間, 充分合並後只剩餘若干個\({1}\)和若干個\({0}\), 形如\({111100}\).
我們維護一個線段樹, 對於每個區間維護\({1}\)的數量和\({0}\)的數量, 再用線段樹分別對於\({1}\)和\({0}\)處理出區間最大值.
合併時兩個區間中間同時消去\(min(0_{Left},1_{Right})\), 再將剩下區間的線段樹合併.