Data Stucture Notes
Data stucture notes for coding competitions.
Content
- BST
- Monotone Queue
- Block List
- Merge-Find Set
- Split & Join AVL
- Persistent AVL
BST
map
- Dictionary
- Insertion, deletion, searching
lower_bound
,upper_bound
- Find element in range
For Fans of Statistics Hardwood Species
Monotone Queue
- Basic operations
push
inO(1)
pop
inO(1)
max
/min
inO(1)
- Implementation
Insert(k):
while (queue not empty) and (tail element >= k):
discard tail
append k to tail
Min():
return head of queue
Block List
- Structure
- Partition indices into
O(sqrt(n))
segments, each of lengthO(sqrt(n))
- Partition indices into
- Basic operations
insert
delete
- Range operation on
[i,j]
inO(sqrt(n))
- Implementation
Insert(x):
# invariant: each segment has elements >= L and < 3L; OR only one segment < 3L
locate segment S # O(sqrt(n))
brute force insertion on S # O(L)
if size(S) == 3L:
evenly split into 2 segments
Delete(x):
locate segment S # O(sqrt(n))
brute force deletion on S # O(L)
if size(S) == L and S has adjacent segment:
combine 2 segments
evenly split into 2 segments
# range operation
# change & sum as example
## change [i,j] to x
Change(i, j, x):
if i == l and j == r: # O(1)
b = true
y = x
s = x * (r - l + 1)
else: # O(L)
if b == true:
set every element in [l,r] to y
b = false
set every element in [i,j] to x
calculate s
## query [i,j]
Query(i, j):
if i == l and j == r: # O(1)
return s
else: # O(L)
if b == ture:
set every element in [l,r] to y
b = false
set every element in [i,j] to x
calculate s
return s
Merge-Find Set
- Structure
- A ground set
S
- A collection
C
of subsets ofS
where 2 different elements inC
are disjoint
- A ground set
- Basic operations
union
: union 2 subsetsfind
: find the subset a specific elememt is intest
: test where 2 elements are in the same subset
- Implementation (linear)
P: P[i] = parent of i in S
F(P): forest difined by P
Find(x):
while P[x] != x:
x = P[x]
return x # root
Union(x):
P[Find(x)] = Find(y)
Test(x, y):
return Find(x) == Find(y)
- Implementation (optimized)
R: rank of element; init R = {0}
Find(x): # path compression
if P[x] != x:
P[x] = Find(P[x])
return x
Union(x): # union by rank
x' = Find(x)
y' = Find(y)
if R[x'] < R[y']:
P[x'] = y'
elif R[x'] > R[y']:
P[y'] = x'
else:
P[x'] = y'
R[y']++
Extension 1: Maintaining the Difference
For each element i
, V[i]
is the underlying unknown integer. Information V[j] - V[i] = k
comes.
- Problem
- Consistent with previously known information?
- If consistent, record the information
V[j] - V[i]
uniquely determined?- If unique, answer the value
- Implementation
D: difference; D[i] = V[i] - V[P[i]]; init D = {0}
Find(x):
if P[x] != x:
(P[x],d) = Find(P[x])
D[x] += d
return (x, D[x])
Union(i, j, k): # V[i] - V[j] = k
(x',D[i]) = Find(i)
(y',D[j]) = Find(j)
if R[x'] < R[y']:
P[x'] = y'
D[x'] = D[j] - D[i] - k
elif R[x'] > R[y']:
P[y'] = x'
D[y'] = D[i] - D[j] - k
else:
P[x'] = y'
D[x'] = D[j] - D[i] - k
R[y']++r
Apply the data structure
- Provided
V[j] - V[i] = k
:Union(i,j,k)
- Answer
V[j] - V[i]
: ifTest(i,j)
thenreturn D[j] - D[i]
- Provided
Extension 2: XOR
Split & Join AVL
- Basic operations
join
:T1
&T2
are AVL trees, and any keyword inT1
is less than any keyword inT2
. Return a union inO(|h(T1)-h(T2)|)
split
: returnT1
with keywords less thank
&T2
with keywords larger thank
inO(h(T))
insert
:split(T,x)
: returnjoin(T1,{x},T2)
delete
:split(T,x)
: returnjoin(T1,T2)
intervalSelection
: returnT
with elementsk1 <= e <= k2
intervalCut
: cut out intervallinkAndCut
:intervalCut
and link to another place- other statistic maintainenance e.g. min, max, sum
Persistent AVL
AVL is link based, and modification operations are join
& split
. Each time O(logn)
nodes visited and modified. Create a copy of root
to modified nodes.