首先能夠想到列舉所有的 /
,對於每個 /
計算以它為中間字元時能夠產生的最大答案。對於當前詢問的區間 \((l,r)\),設 \(pos\) 表示當前這個 /
的位置。如果令 \(s1\) 表示區間 \([l,pos]\) 裡 1
的數量,\(s2\) 表示區間 \([pos,r]\) 裡 2
的數量,那麼此時的答案顯然就是 \(\min(s1,s2)+1\)。其中 \(s1\) 和 \(s2\) 可以用字首和維護。
但是直接列舉肯定是不行的。我們不妨感性理解一下,作為斷點字元的 /
一定要儘可能靠近中間,於是不難想到二分。
具體的,我們預處理所有 /
的位置,每次先二分找到所有在當前詢問範圍內的 /
位置區間,設這個區間為 \([L,R]\)。然後在這個集合內二分找到最優的 /
的位置。
在 \(check\) 的時候,我們對於當前的 \(mid\),找到區間 \([L,mid]\) 中 1
的數量 \(sum1\),區間 \([mid,R]\) 中 2
的數量 \(sum2\),那麼如果 \(sum1\le sum2\),就收縮左端點,否則收縮右端點。
二分的收縮,邊界等細節其實不用過多考慮。對於我來說,最後可以把最優位置所在的區間收縮到一個大概不超過 \(10\) 的範圍,在這個範圍裡全部重新計算貢獻,就可以不用考慮邊界問題,足以透過本題。
提交記錄