close

E. George and Cards

這題一看到題目,就想到greedy+資料結構去加速。

 

核心思想是找到一段在array 連續的數字,使得要刪除的數字是裡面最小的。

 

首先找到目前最小要刪除的數字 m

 

令 m 在 array 的index 是 pos[m] 

 

l 為此段最左, r為此段最右。

 

那麼就找到w = r - l + 1,但是在 [l,r] 中有些數字已經刪除了,利用 BIT 去記錄,所

 

以真正的 w = r - l + 1 - ( read(r) - read(l-1)) ;

 

這樣的做法有二個重要的地方。

1. 找到目前最小要刪除的數字。

 記錄哪些要刪掉,然後用 sort

2. 找 l ,r 。

我利用segment tree 做 RMQ + binary search

對於l, 從segment tree 的觀點,我已經知道我要找的qr = pos[m] , 但是ql 並不清楚,這時用 binary search 去找。

對於r , 同上。只是知道ql =pos[m], qr 未知。

 

這是size 是1000000,我的做法 O(n) = n (logn)^2 。就 TLE 了。

 

後來看了其他人的做法還蠻簡單的,sort 原本的 array ,但要記錄原本的 index ( idx array )。開一個 set 叫 s 。

 

從i =1 ... n , i 表示array 的element 數值

 

如果 i 是要刪除的數字那麼

 

l = *(--s.upper_bound(idx[i]));   (A)

r = *(s.upper_bound(idx[i]));    (B)

l++, r--;

w = r - l + 1 - (read(r) - read(l-1));

update(idx[i],1);

 

% update 和 read 函式給 BIT 用的。

 

若非刪除的數字則

  s.insert(idx[i]);

 

原理在於,數字是從小到大考慮,對於一個要刪除的數字,從s.upper_bound (A),(B)得到的l,r一定是某個比

 

現在要刪除的數字還要小的數字,因此若要延伸l,r ,最遠也只能延伸到此。

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 lettice0913 的頭像
    lettice0913

    斑的家

    lettice0913 發表在 痞客邦 留言(0) 人氣()