[Título] para invertir: https://www.luogu.com.cn/problem/P1908
Solución uno: Ley de Violencia para n relativamente pequeña, no se aplica a esta pregunta.
Solución dos: ordenamiento por mezcla.
Podemos llegar fácilmente a encontrar en el orden inverso del tiempo de operación de combinación.
Tomo nota de que apunta a la región izquierda del nodo actual, j puntos a la derecha de la región nodo actual.
Cuando a [i] <= a [j], a [i] es mayor que o igual que el área de la derecha a [j] no constituye cualquier número de orden inverso, al igual que i ++.
Cuando todos los datos a [i]> a [j] cuando, a [j] es mayor que o igual que el área de la izquierda a [i] están configurados en el orden inverso, por lo que el número de inversa + = mediados de l + 1
Debido int desbordamiento, por lo que la suma pasó mucho tiempo
1 #include <iostream> 2 #include <stdio.h> 3 #include <algoritmo> 4 #define N 500010 5 usando espacio de nombres std; 6 7 int n, a [N], c [N]; 8 largo largo suma = 0 ; 9 void mergesort ( int l, int r) { 10 si (l> = r) de retorno ; 11 int mediados = (l + r) >> 1 , k = mediados + 1 , t = l, izquierda = l, = derecha R; 12 mergesort (l, MID); 13 mergesort (mediados + 1 , r); 14 , mientras que (l <= mediados && k <= r) { 15 si (a [l] <= a [k]) { 16 c [t ++] = a [l ++ ]; 17 } 18 más 19 c [t ++] = a [k ++], sum + = ( tiempo largo ) mid - l + 1 ; 20 } 21 mientras que (l <= MID) 22 c [t ++] = a [l ++ ]; 23 , mientras que (k <= r) 24 c [t ++] = a [k ++ ]; 25 para (; izquierda <= derecha; izquierda ++ ) 26 un [izquierdo] = c [izquierdo]; 27 } 28 29 int main () { 30 scanf ( " % d " , y n); 31 para ( int i = 1 ; i <= n; i ++ ) 32 scanf ( " % d " , & a [i]); 33 mergesort ( 1 , n); 34 printf ( " % LLD " , suma); 35 de retorno 0 ; 36 }
∠ (° ゝ °)!
Solución tres: árbol Fenwick
Referido a una [i] es la matriz original
Luego cada uno una posición [i] en Fenwick árbol árbol [] en correspondencia somos 1, por lo que a [i] prefijo y representa el pequeño que o igual a su número, entonces el prefijo i- y es inversa para un número.
Entonces ...... desbordamiento.
Debido a que cada número en la secuencia no sea superior a 10 ^ 9, por lo que, ya sabes.
Con el fin de reducir el consumo de espacio, utilizamos discreta.
Será una especie, y cada número en lugar de 1 ...... n consumo, respectivamente, por lo que el tamaño del árbol sólo necesita << 2 de 10 ^ 5, reduciendo en gran medida.
Código es el siguiente:
1 #include <iostream> 2 #include <algoritmo> 3 #include <stdio.h> 4 #define N 500010 5 #define lowbit (x) x y -x 6 typedef largo largo ll; 7 usando espacio de nombres std; 8 9 int n, b [N], árbol [N << 2 ]; 10 struct nodo { 11 int val, num; 12 } a [N]; 13 14 // inline作用和definir差不多 15 inline bool cmp (nodo a, nodo b) { 16 Si (a.val == b.val) retorno a.num < b.num; 17 de retorno a.val < b.val; 18 } 19 void inserto ( int x, int k) { 20 mientras que (x <= n) { 21 árbol [x] + = k; 22 x + = lowbit (x); 23 } 24 } 25 consulta ll ( int x) { 26 ll ans = 0 ; 27 , mientras que (x) { 28 ans + =Árbol [X]; 29 X - = lowbit (X); 30 } 31 es retorno ANS; 32 } 33 es 34 es int main () { 35 Scanf ( " % D " , y n-); 36 para ( int I = . 1 ; I <= N-; I ++ ) 37 [ Scanf ( " % D " , A & [I] .val), A [I] .num = I; 38 es // discretización, también evitar que algún número, derivada del espacio de rebose 39 Ordenar (A + . 1 , + n-A + 1. , CMP); 40 para ( int i = 1 ; i <= n; i ++ ) 41 b [a [i] .num] = i; 42 ll ans = 0 ; 43 para ( int i = 1 ; i <= n; i ++ ) { 44 inserto (b [i], 1 ); 45 ans + = i- consulta (b [i]); 46 } 47 printf ( " % LLD " , ans); 48 de retorno 0 ; 49 }