Codeforces Round #397 (Div. 1 + Div. 2 combined) F.Souvenir
洛谷傳送門
題目描述
Artsem is on vacation and wants to buy souvenirs for his two teammates. There are souvenir shops along the street. In shop Artsem can buy one souvenir for dollars, and he cannot buy more than one souvenir in one shop. He doesn’t want to introduce envy in his team, so he wants to buy two souvenirs with least possible difference in price.
Artsem has visited the shopping street times. For some strange reason on the day only shops with numbers from to were operating (weird? yes it is, but have you ever tried to come up with a reasonable legend for a range query problem?). For each visit, Artsem wants to know the minimum possible difference in prices of two different souvenirs he can buy in the opened shops.
In other words, for each Artsem’s visit you should find the minimum possible value of where , .
輸入輸出格式
輸入格式:
The first line contains an integer ( ).
The second line contains space-separated integers ( ).
The third line contains the number of queries ( ).
Next lines describe the queries. of these lines contains two space-separated integers and denoting the range of shops working on day ( ).
輸出格式:
Print the answer to each query in a separate line.
輸入輸出樣例
輸入樣例#1:
8
3 1 4 1 5 9 2 6
4
1 8
1 3
4 8
5 7
輸出樣例#1:
0
1
1
3
解題分析
考慮離線詢問, 按右端點排序, 將原來元素從左到右逐個插入線段樹, 進而修改所有右端點在的答案, 保證當一個詢問右端點為的時候, 我們剛好插入到的位置。線段樹每個節點維護區間元素的有序序列, 便於查詢前驅後繼, 再記錄一個當前區間在插入到的時候的最優解。
不難發現, 右端點一定的情況下, 一個區間的答案隨左端點的右移單調不減。 這是因為左端點更靠左的區間包含了靠右的區間, 這樣我們就可以記錄當前的最優解, 優先更新右區間。 如果最優解優於在當前區間能取到的最優解, 我們就沒有必要再遞迴下去更改。
考慮如何和會達到最大的複雜度: 左邊每一個點都與插入點的差小於最優解,一次更新會更新到最左邊的葉節點, 我們可以這樣構造:
或
這樣構造出來的序列期望每次更新長度為個葉節點, 所以每次更新的複雜度上限為, 總複雜度為。
每個區間可以不用維護有序的區間元素, 在建樹的時候用記錄葉節點的元素再一路歸併上來就好了。