[Dividir e conquista, a intercalação inversa]

[Dividir e conquista, a intercalação inversa]

título

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 é:
Aqui Insert Picture Descrição

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;
}
Publicado 75 artigos originais · ganhou elogios 1 · vista 3655

Acho que você gosta

Origin blog.csdn.net/A793488316/article/details/104567590
Recomendado
Clasificación