contents
Problem
You are given a permutation {1,2,3,…,n}. Remove m of them one by one, and output the number of inversion pairs before each removal. The number of inversion pairs of an array A is the number of ordered pairs (i,j) such that i < j and A[i] > A[j].
Input
The input contains several test cases. The first line of each case contains two integers n and m (1<=n<=200,000, 1<=m<=100,000). After that, n lines follow, representing the initial permutation. Then m lines follow, representing the removed integers, in the order of the removals. No integer will be removed twice. The input is terminated by end-of-file (EOF). The size of input file does not exceed 5MB.
Output
For each removal, output the number of inversion pairs before it.
Sample Input
|
|
Output for the Sample Input
|
|
Explanation
(1,5,3,4,2)->(1,3,4,2)->(3,4,2)->(3,2)->(3)
Solution
題目描述:
找尋一維數列的逆序對總數,每一次詢問請輸出當時的逆序對個數,隨後將該數字從數列中移除。
題目解法:
一開始可以利用傳統的 D&C 或者是線段樹之類的區間查詢來完成全部的逆序對總數。
隨後要移除某個特定的數字時,要查找該數字前面有多少比它大的數字,以及後面有多少比它小的數字。也就是說,找尋前綴大於某個數字的個數,和找尋後綴小於某個數字的個數,算出有多少對逆序對減少。
這裡使用類似歸併樹的做法,類似合併排序,將會切分成數個區間做排序。並且在每一個區間中會建立一棵離散化後的 binary indexed tree,如果一來記憶體可以在 O(n log n) 解決。
由於我們只需要前綴和後綴的操作,所以說是線段樹可能還有所不及。
每次將前綴拆分成線段樹的數個區間,利用 binary indexed tree,查找當前有多少小於該數字 x 數字被刪除,得到有多少小於 x 的數字還存在 … 之後就可以得到需要的個數。
詳見代碼。
|
|