複習題:luogu題單
\(1.\)
noi2015 品酒大會
題意:\(\forall i∈[0,n)\)求有多少對字尾滿足\(lcp \ge i\),以及滿足條件的兩個字尾的權值乘積的最大值。
我們統計出對於\(1...n\)中的每個\(i\)統計一下有多少個\(lcp=i\)再做個字尾和。
因為\(lcp(i,j)=min_^st_\times ed_i\),複雜度\(o(n^2)\),這樣就可以拿到\(95pts\)了,最後5pts打表就行了。
考慮如何更快的求出\(st\)和\(ed\),我們列舉 \(aa\) 型字串中\(a\)的長度\(l\)。每隔\(l\)格放乙個關鍵點,即在\(l,2l,3l...\)位置放關鍵點。顯然,乙個長度為\(2l\)的 \(aa\) 型字串應當經過恰好兩個關鍵點。
設\(lcp(i,j)\)為以\(i,j\)字尾開頭的最長公共字首,\(lcs(i,j)\)為以\(i,j\)字尾結束的最長公共字尾,這個可以建正反串字尾陣列求出。考慮兩個相鄰的關鍵點\(i,j\),其中\(i+l=j\) ,那麼顯然當\(lcp(i,j)+lcs(i,j) \ge l\)時產生了貢獻,貢獻為\(lcp(i,j)+lcs(i,j)-l+1\)
如圖紅色是\(i,j\),藍色和綠色分別是\(lcp\)和\(lcs\),其中粉色是\(aa\)串,而這個\(aa\)串可以一直向後滑動到棕色部分,滑動中經過的串的個數就是\(lcp(i,j)+lcs(i,j)-l+1\),所以我們把紅色加粗部分的所有\(st_i\)加\(1\),把綠色加粗部分的所有\(ed_i\)加\(1\),這個用差分實現即可。
\(3\).noi2018 你的名字
題意: 給你乙個字串\(s\), 多次詢問給定乙個\(t\), 求\(t\)中不在\(s[l...r]\)**現的本質不同的子串個數。
老套路,把詢問離線,把所有串用乙個特殊字元連在一起做字尾陣列。
我們按順序列舉\(t\)的每個字尾\(i\),我們求出最大的長度\(l\)使得\(\large t[i,i+l-1]\)是\(s[l...r]\)的子串,那麼長度小於\(l\)的顯然都不滿足條件,可以直接計算。這個\(l\)是可以二分的,但是我們發現所有的\(i+l-1\)這個位置隨著\(i\)的增大是單調上公升的,所以雙指標即可。
所以現在只要判斷乙個\(l\)是否可行。事實上就是查詢\(s[l...r-l+1]\)中是否存在乙個\(k\)使得\(lcp(k,i) \ge l\),我們先求出滿足這個條件的\(k\)在字尾陣列上的區間\([le,ri]\),然後判斷\([le,ri]\)中是否存在乙個字尾\(k \in [l,r-l+1]\),使用主席樹查詢即可。
用本質不同子串個數減去上述得到的答案即可。
時間複雜度\(o(nlog_2n)\),注意常數。
\(4.\)[heoi2016/tjoi2016 字串
考慮二分答案,二分乙個\(l\)只需要判斷是否存在乙個\(k \in [b-l+1,b]\)使得\(lcp(k,c)=l\),根據上題的做法,先二分求出在字尾陣列的對應的區間\([le,ri]\),然後主席樹查詢即可。
時間複雜度\(o(nlog_2^2n)\)
\(5.\)cf504e
先樹剖再按\(dfn\)序建立正反字尾陣列,跳重鏈的時候記錄下重鏈的左右端點,然後拼起來。
每次我們用\(st\)表求出\(lcp(i,j)\)然後根據長度判斷是否還能向擴充套件。
因為兩個點之間重鏈個數最多只有\(2log_2n\)個,所以我們最多比較\(4log_2n\)次。
這個做法常數很小,最慢的點只要2s,目前我的賬號周
小涵是\(luogu\)的最優解。
\(6\).cf666e
老套路,把所有串用乙個特殊字元連在一起做字尾陣列。
容易發現答案就是對於所有滿足\(lcp(pl,k) \ge pr-pl+1\)中\(col_k \in [l,r]\)的眾數。
我們考慮將詢問按 \(pr-pl+1\) 從大到小排序,再把\(heiht_i\) 也從大到小排序,用兩個指標,乙個指向當前詢問,乙個指向當前的\(heiht_i\),我們將所有\(height_i \ge pr-pl+1\)的進行合併操作。也就是把\(i\)和\(i-1\)所在的集合合併,用資料結構維護眾數即可,很顯然用並查集+線段樹合併可以很好的維護這個資訊。這題的做法和noip2013 貨車運輸的思想是一樣的,所以事實上也可以用\(kruskal\)重構樹維護眾數。
\(7.\)
cf1037h
我們列舉答案與\(t\)的\(lcp\)長度\(l\),找出在字尾陣列上對應的區間\([l,r]\),因為新增乙個字元只會使區間縮小,所以我們用兩次二分可以確定新一輪\([l,r]\)。
我們再枚第\(l+1\)個應該填什麼字元,這個字元應滿足字典序是大於原字串的對應位置的字元,按照上述同樣的方法求出\([l,r]\),然後判斷\([l,r]\)中是否\(\exist~sa_k\in[le,ri-l]\),這個用主席樹維護即可。
CodeChef題目選講
關鍵點 不超過7條 根據咕咕原理,所以答案最少是n 7 n小於49就暴力 隨機化找兩個點判斷直線上的點個數,隨機500次,概率就很高了 法二 點數大於50,答案至少是8 答案一定是7條路之一 隨機找7個點,按照級角序排序,點數大於7的直線就刪去上面的點 之後random不考慮,但是實際上不能真刪除,...
貪心題目選講
假定海岸線是一條無限延伸的直線,陸地在海岸線的一邊,大海在另一側。海中有許多島嶼,每乙個小島我們可以認為是乙個點。現在要在海岸線上安裝雷達,雷達的覆蓋範圍是d,也就是說大海中乙個小島能被安裝的雷達覆蓋,那麼它們之間的距離最大為d。我們使用平面直角座標系,定義海岸線是x軸,大海在x軸上方,陸地在下方。...
樹狀陣列選講
樹狀陣列 binary indexed tree bit fenwick tree 是乙個查詢和修改複雜度都為log n 的資料結構。主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改乙個元素的值 經過簡單修改可以在log n 的複雜度下進行範圍修改,但是這時只能查詢其中乙個元素的值。樹狀陣列...