patternMinor
Structure for getting $| \{ a,b \} \subset S : a+b \le d|$ in O(1)
Viewed 0 times
gettingsubsetforstructure
Problem
I am struggling with exercise from the old algorithmic exam:
$d$ is const for the whole structure.
Propose a structure for which you can do:
I am trying to that with AVL Tree with additional members like number of nodes such that $v.value+u.value \le d$.
Could somebody give me some hint?
$d$ is const for the whole structure.
Propose a structure for which you can do:
- Init(S) //called only 1 time
- Insert(x, S):: $ S := S \cup \{x\}$ in O(log(|S|)
- Delete(x, S):: $ S := S \setminus \{x\}$ in O(log(|S|)
- Get(S) = $| \{ a,b \} \subset S : a+b \le d|$ in O(1)
I am trying to that with AVL Tree with additional members like number of nodes such that $v.value+u.value \le d$.
Could somebody give me some hint?
Solution
It is on the right direction to try some kind of tree augmented with a global counter that stores the number of all unordered pairs of nodes $\{u,v\}$ such that $v.value+u.value \le d$.
The kind of tree you are looking for is a balanced (binary) search tree. Being balanced such as an AVL tree, it supports insertion, deletion and lookup of a number with $O(\log|S|)$ time. Being sorted as well, it can also update that global counter in $O(\log|S|)$ time if we can maintain some extra information on each node of the tree.
What should be those extra information? One approach is that each node $v$
will have a member $lcount$ that stores the number of nodes in its left subtree as well as a member $rcount$ that stores the number of nodes in its right subtree.
To simplify the explanation, let us use AVL tree. We will assume all values are distinct; otherwise, we can add a duplicity counter to each node.
Each insertion or deletion involves at most two tree rotations. Each rotation changes the edges between at most several nodes. So we can update all $lcount$ and $rcount$ in $O(\log|S|)$ time.
Before the insertion of node $n$, we should compute the number of nodes whose values are not greater than $d - n.value$, which is one plus the number of nodes to the left of the node $m$, whose value is the greatest but no greater than $d-n.value$. With the insertion of $n$, we will keep the global_counter intact if there is no such node $m$. Otherwise, letting $ancestor$ be $m$, we will do the following.
The case of deletion is similar to the case of insertion.
Further explanation will be omitted.
Thanks to OP, who contributed to this answer.
The kind of tree you are looking for is a balanced (binary) search tree. Being balanced such as an AVL tree, it supports insertion, deletion and lookup of a number with $O(\log|S|)$ time. Being sorted as well, it can also update that global counter in $O(\log|S|)$ time if we can maintain some extra information on each node of the tree.
What should be those extra information? One approach is that each node $v$
will have a member $lcount$ that stores the number of nodes in its left subtree as well as a member $rcount$ that stores the number of nodes in its right subtree.
To simplify the explanation, let us use AVL tree. We will assume all values are distinct; otherwise, we can add a duplicity counter to each node.
Each insertion or deletion involves at most two tree rotations. Each rotation changes the edges between at most several nodes. So we can update all $lcount$ and $rcount$ in $O(\log|S|)$ time.
Before the insertion of node $n$, we should compute the number of nodes whose values are not greater than $d - n.value$, which is one plus the number of nodes to the left of the node $m$, whose value is the greatest but no greater than $d-n.value$. With the insertion of $n$, we will keep the global_counter intact if there is no such node $m$. Otherwise, letting $ancestor$ be $m$, we will do the following.
while ancestor is not null:
if anc.value < m.value:
global_counter := global_counter + ancestor.lcount + 1
ancestor := ancestor.parentThe case of deletion is similar to the case of insertion.
Further explanation will be omitted.
Thanks to OP, who contributed to this answer.
Code Snippets
while ancestor is not null:
if anc.value < m.value:
global_counter := global_counter + ancestor.lcount + 1
ancestor := ancestor.parentContext
StackExchange Computer Science Q#119099, answer score: 2
Revisions (0)
No revisions yet.