Permutazione inversa#1788

Permutazione inversa (Editoriale)

Una permutazione di ordine è una sequenza p = (p[1], p[2], \ldots, p[n]) in cui ogni numero da a compare esattamente una volta. È conveniente considerare una permutazione come un'applicazione che porta il numero nel numero : i \to p[i].

La inversa di una permutazione è la permutazione p^{-1} che riporta ogni numero al proprio posto: se porta in , allora p^{-1} riporta in . In altre parole, per tutti gli vale la seguente uguaglianza:

p^{-1}[p[i]] = i

Questa uguaglianza fornisce direttamente l'algoritmo: il numero deve trovarsi nella posizione della permutazione inversa. Si itera su tutti gli da a e si esegue per ciascuno l'assegnazione pi[p[i]] = i, dove l'array memorizza la permutazione inversa.

Ogni posizione dell'array viene riempita esattamente una volta. Infatti, i valori p[1], p[2], \ldots, p[n] sono a due a due distinti e coprono tutti i numeri da a , quindi anche gli indici sono a due a due distinti e coprono tutte le posizioni da a .

Notazione a due righe. Una permutazione viene spesso scritta su due righe: la riga superiore contiene i numeri 1, 2, \ldots, n, e sotto ogni numero compare il valore . Per ottenere la permutazione inversa, basta scambiare le righe e ordinare le colonne in ordine crescente rispetto alla riga superiore.

Esempio

Consideriamo la permutazione dell'esempio. Scriviamola insieme alla sua inversa nella notazione a due righe:

p = \begin{pmatrix} 1 & 2 & 3 \\ 2 & 3 & 1 \end{pmatrix}, \qquad p^{-1} = \begin{pmatrix} 1 & 2 & 3 \\ 3 & 1 & 2 \end{pmatrix}

Troviamo p^{-1} usando la formula pi[p[i]] = i:

pi[p[1]] = pi[2] = 1, \quad pi[p[2]] = pi[3] = 2, \quad pi[p[3]] = pi[1] = 3

Otteniamo p^{-1} = (3, 1, 2). La notazione a due righe fornisce lo stesso risultato: scambiando le righe della permutazione , otteniamo le colonne , , . Ordinandole secondo la riga superiore, otteniamo la riga inferiore .

Nella figura, la permutazione è rappresentata come frecce i \to p[i]. Nella permutazione inversa, tutte le frecce puntano nella direzione opposta: p[i] \to i.

Implementazione dell'algoritmo

L'array memorizza la permutazione in input, e l'array memorizza la permutazione inversa.

#define MAX 20010
int p[MAX], pi[MAX];

Leggiamo la permutazione in input.

scanf("%d",&n);
for(i = 1; i <= n; i++)
  scanf("%d",&p[i]);

Calcoliamo la permutazione inversa.

for(i = 1; i <= n; i++)
  pi[p[i]] = i;

Stampiamo la permutazione inversa.

for(i = 1; i <= n; i++)
  printf("%d ",pi[i]);
printf("\n");

Implementazione in Python

La lista memorizza la permutazione in input, e la lista memorizza la permutazione inversa. Leggiamo i dati in input.

n = int(input())
p = [0] + list(map(int, input().split()))
pi = [0] * (n + 1)

Calcoliamo la permutazione inversa.

for i in range(1, n + 1):
  pi[p[i]] = i

Stampiamo la permutazione inversa.

for i in range(1, n + 1):
  print(pi[i], end=" ")
print()