OJ题目:click here~~
题目分析:经典题目,求逆序对。两种方法:
一、离散化+树状数组
二、归并排序
利用归并排序,已A:
AC_CODE
#include<stdio.h>
#include<string.h>
using namespace std ;
typedef long long LL ;
const int maxn = 100008 ;
int n ;
LL ans ;
int x[maxn] ;
void Merge(int low , int high){
int mid = (low + high)/2 ;
int i = low, j = mid + 1, k = 0 ;
int xx[maxn] ;
while(i <= mid && j <= high){
if(x[i] > x[j]){
xx[k++] = x[j++] ;
ans += (mid - i + 1) ;
}
else{
xx[k++] = x[i++] ;
}
}
if(j <= high) while(j <= high) xx[k++] = x[j++] ;
if(i <= mid) while(i <= mid) xx[k++] = x[i++] ;
k = 0 ;
i = low ;
while(i <= high) x[i++] = xx[k++] ;
}
void MergSort(int low , int high){
if(high <= low) return ;
int mid = (low + high)/2 ;
MergSort(low , mid) ;
MergSort(mid + 1 , high) ;
Merge(low , high) ;
}
int main(){
int i , j , k ;
while(scanf("%d",&n) != EOF){
ans = 0 ;
for(i = 0;i < n;i++)
scanf("%d",&x[i]) ;
MergSort(0 , n - 1) ;
printf("%lld\n",ans) ;
}
return 0 ;
}
树状数组,不能A,但是在POJ2299能A。。。。。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
using namespace std;
typedef long long LL ;
const int maxn = 100005 ;
int n ;
int x[maxn] ;
LL c[maxn] ;
struct Node{
int x,order ;
}node[maxn];
bool cmp(const Node &A ,const Node &B){
return A.x < B.x ;
}
int lowbit(int x){
return x&(-x) ;
}
void update(int t , int x){
int i ;
for(i = t;i <= n;i += lowbit(i)){
c[i] += x ;
}
}
int getsum(int x){
int i ,sum = 0 ;
for(i = x;i > 0;i -= lowbit(i)){
sum += c[i] ;
}
return sum ;
}
int main()
{
int i ;
while(scanf("%d",&n) != EOF){
memset(c , 0 , sizeof(c)) ;
for (i = 1;i <= n;i++){
scanf("%d",&node[i].x) ;
node[i].order = i ;
}
sort(node + 1 , node + 1 + n , cmp) ;
for(i = 1;i <= n;i++)
x[node[i].order] = i ;
LL sum = 0 ;
for(i = 1;i <= n;i++){
update(x[i] , 1) ;
sum += (i - getsum(x[i])) ;
}
cout << sum << endl ;
}
return 0;
}
/**************************************************************
Problem: 1348
Language: C++
Result: Wrong Answer
****************************************************************/