Difficulty in few steps in proof of “Amortized cost of $\text{Find-Set}$ operation is $\Theta(\alpha(n))$”assuming union by rank, path compression

I was reading the section of data structures for disjoint sets from the text CLRS I faced difficulty in understanding few steps in the proof of the lemma as given in the question title. Here we assume we follow union by rank and path compression heuristics. Before we move into our target lemma a few definitions and lemma is required as a prerequisites for the target lemma.

The prerequisites:

$ $ level(x)=\max\{k:rank[p[x]]\geq A_k(rank[x])\}$ $ $ $ iter(x)=\max\{i:rank[p[x]]\geq A_{level(x)}^{(i)}(rank[x])\}$ $ $ $ \phi_q(x) = \begin{cases} \alpha(n).rank[x] &\quad\text{if $ x$ is a root or $ rank[x]=0$ }\ (\alpha(n)-level(x)).rank[x]-iter(x) &\quad\text{if $ x$ is not a root and $ rank[x]\geq1$ }\ \end{cases}$ $

Lemma 21.9: Let $ x$ be a node that is not a root, and suppose that the $ q$ th operation is either a $ \text{Link}$ or $ \text{Find-Set}$ . Then after the $ q$ th operation, $ \phi_q(х) \leq \phi_{q-1}(х)$ . Moreover, if $ rank[x] \geq 1$ and either $ level(x)$ or $ iter(x)$ changes due to the $ q$ th operation, then $ \phi_q(х) < \phi_{q-1}(х) – 1$ . That is, $ x$ ‘s potential cannot increase, and if it has positive rank and either $ level(x)$ or $ iter(x)$ changes, then $ x$ ‘s potential drops by at least $ 1$ .

Now in the proof below I marks the steps where I face problem

Lemma 21.12: The amortized cost of each $ \text{Find-Set}$ operation is $ \Theta(\alpha(n))$ .

Proof: Suppose that the $ q$ th operation is a $ \text{Find-Set}$ and that the find path contains $ s$ nodes. The actual cost of the $ \text{Find-Set}$ operation is $ O(s)$ . We shall show that no node’s potential increases due to the $ \text{Find-Set}$ and that at least $ \max\{0,s – (\alpha(n) + 2)\}$ nodes on the find path have their potential decrease by at least $ 1$ .

To see that no node’s potential increases, we first appeal to Lemma 21.9 for all nodes other than the root. If $ x$ is the root, then its potential is $ \alpha(n) . rank[x]$ , which does not change.

Now we show that at least $ \max\{0,s – (\alpha(n) + 2)\}$ nodes have their potential decrease by at least $ 1$ . Let $ x$ be a node on the find path such that $ rank[x] > 0$ and $ x$ is followed somewhere on the find path by another node $ у$ that is not a root, where $ level(y) = level(x)$ just before the $ \text{Find-Set}$ operation. (Node $ у$ need not immediately follow $ x$ on the find path.) $ \require{color}\colorbox{yellow}{All but at most $ \alpha(n) + 2$ nodes on the find path satisfy these constraints on $ x$ .}$ $ \require{color}\colorbox{yellow}{Those that do not satisfy them are the firstnode on the find path (if it has rank $ 0$ ),}$ $ \require{color}\colorbox{yellow}{ the last node on the path (i.e., the root), and the last node $ w$ on the path for which}$ $ \require{color}\colorbox{yellow}{ $ level(w) = k$ , for each $ k = 0,1,2,…, \alpha(n) – 1$ .}$

Let us fix such a node $ x$ , and we shall show that $ x$ ‘s potential decreases by at least $ 1$ . Let $ k = level(x) = level(y)$ . Just prior to the path compression caused by the $ \text{Find-Set}$ , we have

$ rank[p[x]] \geq A_k^{(iter(x)}(rank[x])$ (by definition of $ iter(x)$ ) ,

$ rank[p[y]] \geq A_k(rank[y])$ (by definition of $ level(y)$ ,

$ rank[y] > rank[p[x]]$ (by Corollary 21.5 and because $ у$ follows $ x$ on the find path)

Putting these inequalities together and letting $ i$ be the value of $ iter(x)$ before path compression, we have

$ rank[p[y]] \geq A_k(rank[y]) \geq A_k(rank[p[x]])$ (because $ A_k(j)$ is strictly increasing) $ > A_k(A_k^{(iter(x)}(rank[x])) = A_k^{(i+1)}(rank[x])$ .

Because path compression will make $ x$ and $ у$ have the same parent, we know that after path compression, $ rank[p[x]] = rank[p[y]]$ and that the path compression does not decrease $ rank[p[y]]$ . Since $ rank[x]$ does not change, after path compression we have that $ \require{color}\colorbox{pink}{$ rank[p[x]]\geq A_k^{(i+1)}(rank[x])$ . Thus, path compression will cause either $ iter(x)$ to }$ $ \require{color}\colorbox{pink}{increase (to atleast $ i + 1$ ) or $ level(x)$ to increase (which occurs if $ iter(x)$ increases}$ $ \require{color}\colorbox{pink}{to at least $ rank[x] + 1$ ). In either case,by Lemma 21.9, we have $ \phi_q(х) \leq \phi_{q-1}(х) – 1$ .}$ $ \require{color}\colorbox{pink}{Hence, $ x$ ‘s potential decreases by at least $ 1$ .}$

The amortized cost of the $ \text{Find-Set}$ operation is the actual cost plus the change in potential. The actual cost is $ O(s)$ , and we have shown that the total potential decreases by at least $ \max\{0,s – (\alpha(n) + 2)\}$ . The amortized cost, therefore, is at most $ O(s) — (s — (\alpha(n) + 2)) = O(s) — s + 0(\alpha(n)) = O(\alpha(n))$ , since we can scale up the units of potential to dominate the constant hidden in $ О (s)$ . ■

In the proof above I could not get the mathematics behind the statements highlighted in yellow and pink. Can anyone help me out?

Is there a way to map the concatenation operation over strings to the addition operation over $\mathbb{N}$

Given an alphabet, say $ \Sigma = \{0,1\}$ , I can make a one-to-one mapping from all possible strings $ x \in \Sigma^*$ to $ \mathbb{N}$ . This could be done by ordering $ \Sigma^*$ lexicographically and assigning the $ i$ th string $ x_i$ to number $ i \in \mathbb{N}$ .

But given strings $ x_i,x_j \in \Sigma^*$ , is there any special mapping such that the concatenation operation $ f:\Sigma^* \rightarrow \Sigma^* | (x_i,x_j) \rightarrow x_ix_j$ is also related to the usual addition performed over the corresponding indices $ i,j \in \mathbb{N}$ to which $ x_i$ and $ x_j$ are mapped ?

For instance, if I assign the character $ \{1\}$ to the number $ 1$ , and string $ x$ is assigned the number $ 10$ , is there a mapping such that the string $ x1$ is assigned the number $ 11$ ? (i.e. $ 10 + 1$ )

$\Phi_1=1$ or $\Phi_1=2$ for the dynamic $\text{Table-Insert}$ , where $\Phi_i$ is the potential function after $i$ th operation, as per CLRS

The following is the section from Introduction to Algorithms by Cormen. et. al. in the Dynamic Tables section.

In the following pseudocode, we assume that $ T$ is an object representing the table. The field $ table[T]$ contains a pointer to the block of storage representing the table. The field $ num[T]$ contains the number of items in the table, and the field $ size[T]$ is the total number of slots in the table. Initially, the table is empty: $ num[T] = size[T] = 0$ .

$ \text{Table-Insert(T,x)}$

$ 1\quad \text{if $ size[T]=0$ }$

$ 2\quad\quad \text{then allocate $ table[T]$ with $ 1$ slot}$

$ 3\quad\quad size[T] \leftarrow 1$

$ 4\quad\text{if } num[T] =size[T]$

$ 5\quad\quad\text{then allocate $ new-table$ with $ 2 • size[T]$ slots}$

$ 6\quad\quad\quad\text{insert all items in $ table[T]$ into $ new-table$ }$

$ 7\quad\quad\quad\text{free $ table[T]$ }$

$ 8\quad\quad\quad table[T] \leftarrow new-table$

$ 9\quad\quad\quad size[T] \leftarrow 2 • size[T]$

$ 10\quad \text{insert $ x$ into $ table[T]$ }$

$ 11\quad num[T] \leftarrow num[T] + 1$

For the amortized analysis for the a sequence of $ n$ $ \text{Table-Insert}$ the potential function which they choose is as follows,

$ $ \Phi(T) = 2.num[T]-size[T]$ $

To analyze the amortized cost of the $ i$ th $ \text{Table-Insert}$ operation, we let $ num_i$ denote the number of items stored in the table after the $ i$ th operation, $ size_i$ denote the total size of the table after the $ i$ th operation, and $ \Phi_i$ denote the potential after the $ i$ th operation.

Initially, we have $ num_0 = 0, size_0 = 0$ , and $ \Phi_0 = 0$ .

If the $ i$ th Table-Insert operation does not trigger an expansion, then we have $ size_i = size_{i-i}$ and $ num_i=num_{i-1}+1$ , the amortized cost of the operation is $ \widehat{c_i}$ is the amortized cost and $ c_i$ is the total cost.

$ $ \widehat{c_i}=c_i+\Phi_i- \Phi_{i-1} = 3 \text{ (details not shown)}$ $

If the $ i$ th operation does trigger an expansion, then we have $ size_i = 2 . size_{i-1}$ and $ size_{i-1} = num_{i-1} = num_i —1$ ,so again,

$ $ \widehat{c_i}=c_i+\Phi_i- \Phi_{i-1} = 3 \text{ (details not shown)}$ $

Now the problem is that they do not make calculations for $ \widehat{c_1}$ the situation for the first insertion of an element in the table (line 1,2,3,10,11 of code only gets executed).

In that situation, the cost $ c_1=1$ , $ \Phi_0=0$ and $ num_1=size_1=1 \implies \Phi_1 = 2.1-1 =1$

We see that $ \Phi_1=1 \tag 1$

So, $ $ \widehat{c_1}=c_1+\Phi_1-\Phi_0=2$ $

But the text says that the amortized cost is $ 3$ , (I feel they should have said the amortized cost is at most $ 3$ , from what I can understand)

Moreover in the plot below,


The text represents graphically the $ \Phi_1=2$ which sort of contracts $ (1)$ , but as per the graph if we assume $ \Phi_1=2$ then $ \widehat{c_i}=3, \forall i$

I do not quite get where I am making the fault.

Finding an MST with one adding and removing vertex operation

I am facing the following problem: Given an undirected complete Euclidean weighted graph $ G(V, E)$ and its MST $ T$ . I need to remove an arbitrary vertex $ v_i \in V(G)$ , and given a vertex $ v_j \notin V(G)$ , I have to calculate the MST of $ G^{‘}((V(G) \backslash \{v_i\})\cup\{v_j\}, (E\backslash\{(v_i, v_k): v_k \in V(G)\})\cup\{(v_k, v_j): v_k \in V(G^{‘})\})$ , i.e, the graph $ G$ with the vertex $ v_j$ (and its respective edges) and without the vertex $ v_i$ (and its respective edges). To solve this, we can apply some well-know MST algorithms, such as Prim’s, Kruskal’s, Borukva’s algorithm. Neverthless, if we do this we would not use the already existing MST $ T$ , i.e., we would calculate a new whole MST. So, I would like to know if there is any way to reuse the existing MST $ T$ .

There are two a similar question to this here (with edges, considering only the removing of them), and here (with vertex, considering only the adding of them).

Wrap key operation in Azure Key Vault – symmetric keys

Could anyone explain why the bolded part of the wrap key description?

Wraps a symmetric key using a specified key. The WRAP operation supports encryption of a symmetric key using a key encryption key that has previously been stored in an Azure Key Vault. The WRAP operation is only strictly necessary for symmetric keys stored in Azure Key Vault since protection with an asymmetric key can be performed using the public portion of the key. This operation is supported for asymmetric keys as a convenience for callers that have a key-reference but do not have access to the public key material. This operation requires the keys/wrapKey permission.

AFAIK, all the keys in Azure Key Vault are stored at rest in HSM modules. Why is key wrapping necessary for symmetric keys? What does ‘protection’ mean in this case? Using a public key to encrypt data?

If HSM are securing all the keys in Key Vault (using its built-in symmetric key), then why would encrypting a symmetric key be necessary as quoted?

How to deside what model should be picket for security operation center, design and implimentation?

To pick the right model for design and implement a Security Operation Center, it should pick a most suitable model that is for the business, that could be capable to be tailored.

What are the differences, between Best practices, standards, and frameworks in SOC design?

Round down operation result in IEEE 754 [closed]

For operations using single precision values in IEEE 754 (float, 32bit), is there a way to somehow condition the two operands to ensure that the operation result is rounded down, when an exact result is not possible?


  • Typical result (using ’round to nearest’): 1.0f / 3.0f = 0.3333333432674407958984375f
  • Expected result (using ’round down’): 1.0f / 3.0f = 0.333333313465118408203125f

As additional info, I would be doing this in C99, and (unfortunatly) it’s not possible to configure the FPU.

Changing to docker and receiving Illegal mix of collations (latin1_danish_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation ‘=’ error

I am atempting to change our application from a server to a docker on a virtual machine. We are using mysql for data, and tomcat (spring) for the gui. It seems to work well in the docker, execpt for when a stored procedure is called. It gives the error message:

Request processing failed; nested exception is java.lang.RuntimeException: java.sql.SQLException: Illegal mix of collations (latin1_danish_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '=' 

This error message does not occure when the application is run on the server (not the docker version), so I am asuming there is some configuration that I have not been able to transfere from the original application to the docker based application. Since it works with the same data on the server, I don’t think it should be nessesary to change the tables or the procedure.

The docker creates a mysql:5 container and a tomcat:8 contaner and they comunicate thru a docker network. The GUI connects with the database with this line:


I have only changed ‘localhost’ to ‘db’, as tomcat and mysql are on sepperate containers on the docker version. I have tried a few variations of characterEncoding, like latin2, but with no luck.

I have been loking at the config files in /etc/mysql/ but I haven’t found anything that seems relevant.

Does anyone know what settings I have been missing, or what more I can do to futher narriate the problem. I am new in this line of work, and is learning myself bouth docker and mysql while working on this transfer.

best database for storing arrays with set-like sum operation

I need a simple database to store key-array pairs with the ability to update the stored arrays with merging new array into them, without duplicated values. In fact, I need to store ordered “sets”. For example, records in the database looks like:

key : value (an array)

“1” : [ 1, 2, 3, 4]

“2” : [ 1, 3, 5, 7, 11] …

and I want to be able to merge a new array, like [1, 2, 3, 100, 200, 300] into the first record, while skipping duplicates, resulting the first row to become:

“1” : [ 1, 2, 3, 4, 100, 200, 300]

I also want it to handle partial selection of arrays, example:

select myArrayColumn[0:2] where key = 2 

should result: [1, 3]

I want a suggestion for a database with such capabilities.