Search for an integer key using a Y fast trie, combining hashing with balanced trees for linear space.
Y fast trie search improves the space cost of X fast tries by storing only a subset of keys in the prefix structure and grouping the rest into balanced binary search trees.
Instead of storing all prefixes, it samples representatives and maintains buckets of nearby keys. Search combines a fast prefix lookup with a local tree search.
Problem
Given a Y fast trie storing integer keys with word size , determine whether a target key x exists.
Return true if present, otherwise false.
Structure
A Y fast trie consists of two layers:
| component | purpose |
|---|---|
| X fast trie over sampled keys | locate the correct bucket |
| balanced BST buckets | store actual keys |
Keys are partitioned into buckets of expected size .
Each bucket is represented by a key stored in the X fast trie.
Algorithm
First find the predecessor or successor representative in the X fast trie. That identifies the bucket that may contain the key. Then perform a BST search inside that bucket.
y_fast_trie_member(T, x):
r = x_fast_predecessor(T.representatives, x)
if r == null:
return false
bucket = T.bucket[r]
return bst_search(bucket, x)Example
Assume word size and keys:
| key | bucket |
|---|---|
| 3 | [3, 5, 6] |
| 9 | [9, 10, 11] |
| 14 | [14, 15] |
Representatives stored in the X fast trie:
Search for 10:
| step | action |
|---|---|
| 1 | find predecessor representative of 10, which is 9 |
| 2 | select bucket [9, 10, 11] |
| 3 | search inside bucket and find 10 |
Correctness
Each key belongs to exactly one bucket, and the representatives partition the key space.
The X fast trie identifies the representative whose bucket contains all keys in the relevant range. The BST inside that bucket maintains sorted order, so standard BST search correctly determines whether the key is present.
If the algorithm returns true, the key exists in its bucket. If it returns false, the key is not in the bucket, and no other bucket can contain it.
Complexity
Let be the word size.
| operation | time |
|---|---|
| find representative | |
| BST search in bucket | |
| total search |
Space usage:
This improves over X fast tries, which require space.
When to Use
Y fast tries are useful when:
- keys are integers from a bounded universe
- predecessor and successor queries are required
- memory usage must remain linear
- faster than comparison based trees is desired
They provide a practical balance between speed and space for integer search problems.
Implementation
class YFastTrie:
def __init__(self, xfast, buckets):
self.xfast = xfast # X fast trie over representatives
self.buckets = buckets # map representative -> sorted list or BST
def bst_search(bucket, x):
lo, hi = 0, len(bucket) - 1
while lo <= hi:
mid = (lo + hi) // 2
if bucket[mid] == x:
return True
elif bucket[mid] < x:
lo = mid + 1
else:
hi = mid - 1
return False
def y_fast_trie_member(T, x):
r = T.xfast.predecessor(x)
if r is None:
return False
bucket = T.buckets[r]
return bst_search(bucket, x)type YFastTrie struct {
XFast *XFastTrie
Buckets map[uint64][]uint64
}
func BSTSearch(bucket []uint64, x uint64) bool {
lo, hi := 0, len(bucket)-1
for lo <= hi {
mid := lo + (hi-lo)/2
if bucket[mid] == x {
return true
} else if bucket[mid] < x {
lo = mid + 1
} else {
hi = mid - 1
}
}
return false
}
func YFastTrieMember(T *YFastTrie, x uint64) bool {
r, ok := T.XFastPredecessor(x)
if !ok {
return false
}
bucket := T.Buckets[r]
return BSTSearch(bucket, x)
}