[Dividir e conquista, a intercalação inversa]
título Descrição
gato Jerry Tom e concurso de rato recentemente, mas depois de tudo, eles são adultos, eles não gostam de ter que jogar com o tipo de iniciar um jogo, e agora eles gostam de jogar estatísticas.
Recentemente, TOM gato para uma inspeção humana chamada "ordem inversa" material, este material é definido como: para um determinado período de seqüência de inteiros positivos, eo a_j reversa i <j é uma seqüência ordenada de a_i> direita. Sabendo este conceito, quem quer que corresponder a um dado período é calculado número inteiro positivo de sequências na ordem inversa.
Update: Dados foi reforçado.
Formato de entrada
A primeira linha, um número n, existe um número de sequência n.
Segundo número de linha N, a sequência dada. Cada número de sequência não exceda 10 ^ 9
Formato de saída
O número da sequência de saída na ordem inversa.
de entrada de amostra e de saída
Copie entrada # 1
. 6
. 5. 4. 3. 6 1 2
Saída # 1 replicação
11
Descrição / Dicas
Para 25% dos dados, 0n≤2500
Para 50% dos dados, n≤4 × 10 ^ 4.
Para todos os dados, n≤5 × 10 ^ 5
Utilize a entrada e saída mais rápida
análise
Esta necessidade problema para usar merge sort. Mesclar espécie de princípio é:
Então, nós primeiro ler sobre o número ,, cada sub-intervalo de pequeno a grande são merge ordenada após a divisão, que apenas necessita de contabilizar o número de cada esquerdo intervalo e direito, respectivamente, será na ordem inversa de quanto alcance pode ser produzido.
(Porque o número à esquerda, não importa como espécie, ou seja, para que possamos olhar para a esquerda e direita em frente ao número à direita depois de um bom tipo de ordem inversa de quanto produzir o suficiente.
E porque a esquerda está no pequeno a grande porte espécie, desde que a primeira à esquerda> direita do primeiro, em seguida, à esquerda representa todos os números maior do que a primeira à direita,
há muito deixou de contar quantas existem na ordem inversa e depois deixe o segundo para a direita. continue a repetir ( assim que este código é os ans significado + = meio -i +1;)
se a primeira é menor que o primeiro da esquerda para a direita, em seguida, deixar o ponto esquerdo para o segundo, e então continuar ...
Deve ser muito claro agora descrito. . . . Você pode possuir fundindo amostra analógico sob muito clara.
código
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int a[500010],b[500010];
long long ans = 0;
//归并排序的写法都差不多这样
void f(int l,int r){
if(l == r){
return ;
}
int mid = (l+r)/2;
int i= l, j=mid+1, k=l;
f(l,mid);
f(mid+1,r);
while(i<=mid && j<=r){
if(a[i] <= a[j]){
b[k++] = a[i++];
}else{
b[k++] = a[j++];
ans += mid -i +1; //累计有多少对逆序
}
}
while(i<=mid){
b[k++] = a[i++];
}
while(j<=r){
b[k++] = a[j++];
}
for(int i=l;i<=r;i++){
a[i] = b[i];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
f(1,n); //归并 传入1 和总数
printf("%lld",ans);
return 0;
}