Pamięć 16 MB. Czas 1 sek. Permutacja liczb całkowitych od 1 do n jest sekwencją taką, że każda liczba całkowita od 1 do n jest członem sekwencji dokładnie jeden raz. Dwie liczby w permutacji tworzą inwersję, gdy większa jest przed mniejszą. Na przykład, istnieje łącznie 10 inwersji w permutacji 4 2 7 1 5 6 3, utworzonej przez następujące pary: 4-2, 4-1, 4-3, 2-1, 7-1, 7-5, 7 -6, 7-3, 5-3, 6-3. Napisz program, który oblicza liczbę inwersji w danej permutacji.
Wejście
Wartość liczby n(2≤n≤1000000) jest zapisana w pierwszym wierszu standardowego wejścia. Permutacja jest zapisywana w drugim wierszu n liczb rozdzielonych spacjami.
Wyjście
Napisz liczbę inwersji na standardowym wyjściu.
Przykład.
Wejście
7
4 2 7 1 5 6 3
Wyjście
10
Opis:
Do rozwiązania tego zadania należy zastosować algorytm podobny (nawet taki sam) do sortowania przez scalanie. Rekurencyjnie sortowanie dwie podtablice, a następnie scalając podtablice zlicza inwersje.
Rozwiązanie 1:
#include <bits/stdc++.h>
using namespace std;
int ile = 0;
void mer_all(int t[], int l, int v, int r) {
int Lsize = v - l + 1;
int Rsize = r - v;
// tablice pomocnicze
int *t_tmpL = new int[Lsize];
int *t_tmpR = new int[Rsize];
// kopiowanie do tablic pomocnicznych
for(int i=0; i < Lsize; i++) {
t_tmpL[i] = t[l + i];
}
for( int j = 0; j < Rsize; j++) {
t_tmpR[j] = t[v + 1 + j];
}
// laczenie tablic
int iL= 0, iR = 0;
int k;
for(k=l; iL < Lsize && iR < Rsize; k++){
if(t_tmpL[iL]<=t_tmpR[iR]){
t[k] = t_tmpL[iL++];
ile = ile + (v - k + 1) ;
} else {
t[k] = t_tmpR[iR++];
}
}
//Kopiowanie pozosta³ych elementow z tablicy pomocniczej Lewej
while (iL < Lsize)
t[k++] = t_tmpL[iL++];
//Kopiowanie pozosta³ych elementow z tablicy pomocniczej Prawej
while (iR < Rsize)
t[k++] = t_tmpR[iR++];
// usuniecie tabel pomocniczych
delete[] t_tmpL;
delete[] t_tmpR;
}
void merge(int t[], int left, int right) {
if(right>left){
int v = (right+left)/2;
merge(t, left, v);
merge(t, v+1, right);
mer_all(t, left, v, right);
}
}
int inwersja(int t[], int n) {
merge(t,0,n-1);
return ile;
}
int main()
{
int n = 7;
int t[n]={4,2,7,1,5,6,3};
cout << inwersja(t, n);
return 0;
}