題目描述
定義只由(
和)
組成的序列為括號序列。
定義乙個括號序列是合法的,當且僅當它的任意乙個字首都滿足(
的數量不少於)
的數量,且整個序列中(
和)
的數量是相等的。
定義乙個括號序列是 「好的」,當且僅當存在兩個子串行,滿足二者的並集為原序列(但不必不重疊),並且每個子串行都是合法的括號序列。
現在,給定乙個長為 n
nn 的括號序列。有 m
mm 次詢問,每次詢問給定乙個區間 [l,
r]
[l,r]
[l,r
],你需要求出 [l,
r]
[l,r]
[l,r
] 中有多少個子區間是 「好的」 括號序列。
資料範圍與提示
n ,m
≤3×1
05
n,m≤3\times 10^5
n,m≤3×
105,1≤l
≤r≤n
1≤l≤r≤n
1≤l≤r≤
n 。考慮暴力檢查每個子區間。有乙個挺不錯的貪心思路:為了避免右括號過多,遇到左括號就加入兩個子串行,遇到右括號就只加入乙個子串行。如果過程中沒有左括號不夠用的情況,那就只可能有左括號剩餘。下文中,都用 a
aa 表示左括號數量,用 b
bb 表示右括號數量。
最初我認為,只要左括號的剩餘不超過 a
aa 即可,也就是可以退還一些(
。但是)
也是可以加的啊!那就不是 ≤a+
b\le a+b
≤a+b
這麼簡單了,因為此時)
的位置同樣重要。(我就是被())(
輕鬆的 hac
k\rm hack
hack
掉的。)
其實,只要把原序列翻轉(翻轉時會讓(
和)
互換)再做一遍就行了。翻轉前,保證了右括號不會太多。翻轉後,保證了左括號不會過多。——這是感性的證明。理性的證明如下:只要找到乙個分界點,使得字首的 2a1
−b
12a_1-b_1
2a1−b
1等於字尾的 2b2
−a
22b_2-a_2
2b2−a
2,就可以字首按照第一遍的貪心填,字尾按照翻轉後的貪心填。
假設它不成立。當 i=0
i=0i=
0 時,字首的 2a1
−b1=
02a_1-b_1=0
2a1−b
1=0
所以 2b2
−a
2>
02b_2-a_2>0
2b2−a
2>
0 。同理,i=n
i=ni=
n 時 2a1
−b
1>
02a_1-b_1>0
2a1−b
1>
0 。故而 2a1
−b
12a_1-b_1
2a1−b
1與 2b2
−a
22b_2-a_2
2b2−a
2的大小關係有過變化。而二者的差值的變化量是 ±
1\pm 1
±1(分類討論一下當前是(
還是)
即可知),所以過程中必然相交。相交則有解。
從證明中跳出來——我們已經知道,子區間是 「好的」 的充要條件了,即字首和 ≥
0\ge 0
≥0與字尾和 ≥
0\ge 0
≥0。不妨先看一看字首和如何維護。
從小到大列舉右端點,線段樹維護字首和的區間最小值,修改時,如果乙個區間的最小值 <
0<0
<
0 了,就遞迴往下來刪除它。由於每個點做多被刪除一次,總複雜度還是 o(n
logn)
\mathcal o(n\log n)
o(nlogn)
的。然後考慮字尾和如何維護。這個可以對於每個點預處理 l
il_i
li 為,使得 [li
,i
][l_i,i]
[li,i
] 的所有字尾和都 ≥
0\ge 0
≥0的最小 l
il_i
li 。用單調棧預處理——本質是,求字首和第乙個比自己大的。
最後乙個問題:怎麼統計答案?就是這個問題把我一下子難倒了。我還覺得需要用可持久化的黑科技,將很多線段樹給 「重疊」 在一起。其實這個問題還是思維定式,我始終覺得需要在 r
rr 這裡計算答案。其實,權值可以放到左端點上。線段樹上打乙個標記,表示 「沒有被刪除的 l
ll 對應的答案加一」,實際含義就是,對於每個 l
ll 儲存了 ∀r∈
[l,r
]\forall r\in[l,r]
∀r∈[l,
r]有多少個 「好的」 子區間 [l,
r]
[l,r]
[l,r
] 。然後詢問就是區間查詢了。
複雜度 o(n
logn)
\mathcal o(n\log n)
o(nlogn)
,只有乙個線段樹。
Elasticsearch之集群腦裂
集群腦裂是什麼?所謂腦裂問題 類似於精神 就是同乙個集群中的不同節點,對於集群的狀態有了不一樣的理解。由於某些節點的失效,部分節點的網路連線會斷開,並形成乙個與原集群一樣名字的集群,這種情況成為集群腦裂 split brain 現象。這個問題非常危險,因為兩個新形成的集群會同時索引和修改集群的資料。...
Elasticsearch之集群腦裂
所謂腦裂問題 類似於精神 就是同乙個集群中的不同節點,對於集群的狀態有了不一樣的理解。由於某些節點的失效,部分節點的網路連線會斷開,並形成乙個與原集群一樣名字的集群,這種情況成為集群腦裂 split brain 現象。這個問題非常危險,因為兩個新形成的集群會同時索引和修改集群的資料。1.網路 由於是...
從此「錯位」變「裂項」,計算不再讓人狂
已知 a n 2n 1 2 n 求該數列的前 n 項和 s n.設 a n a n 1 b 2 an b 2 n 則 rightarrow a 2,b 3 rightarrow a n 2 n 1 3 2 2n 3 2 n rightarrow s n 2 2 2 3 cdot 2 3 2 2 5 ...