網頁

Sunday 31 October 2010

劃分樹

Definition


給出一條array A[], 對A[]建立劃分樹可以在 O(log N) 時間內解決
1. query(x,y,k) : 在 A[x..y]中的第k小元素
2. rank(x,y,k) : A[k] 在 A[x..y] 內排第幾

Structure


劃分樹和 segment tree 相似, root 代表 [1,n], 兩個 child 為 [1, n/2], [n/2+1, n]
每一個 node 是一條 array

Root是原本的A[]
然後, 把較少的一半分到 left subtree, 較大的一半分到 right subtree, 而各自的相對次序不變

例如
Root = [3 1 5 4 6 8 2 7]
Left child = [3 1 4 2]
Right child = [5 6 8 7]


同時要記著哪些元素分到了左子樹
以上面為例

[3  2  8  4  6  5  1  7]
[3  2  4  1][8  6  5  7]
[2  1][3  4][6  5][8  7]
[1][2][3][4][5][6][7][8]

Query


對於 query(x,y,k)
可視為 "在 [1,n] 入面 [x,y] 中的第k元素"
然後就要發揮二元樹的精神: 把問題 reduce 做一半

先判斷我們要的答案在 left subtree 還是在 right subtree
就可以把問題 reduce 成
"在 [1, n/2] 入面 [x', y'] 中的第 k' 元素" 或
"在 [n/2, 1] 入面 [x'', y''] 中的第 k' 元素"

那些 x',y',k' 怎樣計出來
方法不外乎利用記了哪些元素分到左子樹

至於 rank(x,y,k), 則原理相近

Implement


為方便起, 先把 A[] 離散化
就可以快速判斷分去 left subtree 還是 right subtree

然後棵 tree 其實是 log N 條 array
因為每一層都要記 N 個element的資料

記錄哪些元素分到了左子樹實際上是記 "在這個 node 中, 每個 element 左邊有多少個分到左子樹"
可用 partial sum 解決之
因為計那些 x', y', k' 等等都要用到 partial sum

其實 code 不長
不過細節很煩, 計 index 的式有 4-5 個 variable
寫了一次後便放入武器庫

Wednesday 27 October 2010

SRM 486

300
直接DFS
一開始沒看到先比較length, 以為是直接按lexicographical order, 浪費了一些時間


450
想了一陣覺得memorization dp可行, 時間主要花在coding上
神奇地過到sample, 於是便很有信心地submit


1000
看完題目後很興奮, 因為和CUHK ACM TFT其中一題非常相似
由於有武器, 以division 第二的速度完成了!


種種因素令我在system test前在division排第九


可是..
system test 悲劇了
1000 failed system test
原因竟然是 n=1 的時侯炒了orz... (本來還想一舉破2000的.. 唉)


唉.. 灰鳥
不過結論是, 要保持rating穩步上升, 至少要做到兩題或以上
意外炒了一題也不至於太傷

Monday 18 October 2010

ZOJ 2676 Network Wars

Problem statement: Given a undirected graph, each edge has a cost c, select k edges to disconnect vertex 1 and N, the goal is to minimize c/k

直覺是 binary search 答案
對每條edge, 如果 cost[x][y] < mid, 則直接選取
對餘下的 edge 做 flow 搵 min cut

算法不難想到, 比較挑戰的是 handle precision
發現有些位寫
R < 1e-8 WA
R <= 0 AC
後來想到可能是因為做 flow 的部份和用 dfs 搵 cut set 的 handle 方法要一致

係段 code 既邊個位用 epsilon 也要小心處理

Saturday 16 October 2010

Team Training 13/10/2010 - Phuket 2009

Training 時做不到 K, 在 Joe 的指點下現在做到了
是帶cost的lower bound flow

Problem statement:
Given a directed graph, each edge has 2 cost: Patrol cost and Video cost. Each edge must be either patrol or video, the in-degree of patrol road must equals the out-degree of patrol road on each node. Some edges are pre-assigned to be patrol road. At least one road must be patrolled.

看下去很多條件..
入度和出度其實implies patrol edge是一個個的cycle
所以題目其實是要找一些patrol cycle 去 minimize total cost

先假設所有edge都是video, 每條edge的cost便是轉為patrol的費用

第一步是滿足有些edge必定是patrol的條件
用lower bound做circulation
先不用理cost, 找一個任意的feasible flow

第二步處理cost
其實就是不斷在residual network找negative cycle
用bellman-ford做時, 要注意即使第V個iteration update了node x 並不implies node x 是在 negative cycle 中

最後處理at least one edge must be patrolled
即係搵minimum cycle
由於沒有限定cycle length一定要>2, 可以直接用floyd-warshall做


做完這題終於搞清了lower bound flow的一些概念
有Source和Sink的graph如果有cycle做lower bound flow是NP的

Team Training 11/10/2010 - SWERC 2006