逆序对

关于逆序对的两种解法

其实归并排序似乎快一点
。。。

1.离散化+树状数组

#include<cstdio>
#include<algorithm>
using namespace std;
//int a[1000007];
#define lowbit(x) x&(-x)
int b[1000007],tree[1000007];
struct node{
	int x,id;
	bool operator < (const node&a)const {
		return x<a.x;
	}
}a[1000007];
int n;
void update(int x) {
	while(x<=n) {
		tree[x]+=1;
		x+=lowbit(x);
	}
}
int query(int x) {
	int ans=0;
	while(x>=1) {
		ans+=tree[x];
		x-=lowbit(x);
	}
	return ans;
}
int main () {
	scanf("%d%",&n);
	for(int i=1;i<=n;++i) {
		scanf("%d",&a[i].x);a[i].id=i;
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)b[a[i].id]=i;
	//build();
	int ans=0;
	for(int i=1;i<=n;i++) {
		update(b[i]);
		ans+=i-query(b[i]);
	}
	printf("%d\n",ans);
	return 0;
}

2.归并排序

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=40007;
int a[maxn];
int n,ans;
int t1[maxn],t2[maxn],b[maxn];
void merge(int l,int r) {
    if(l==r)return;
    int mid=(l+r)>>1;
    merge(l,mid);
    merge(mid+1,r);
    int i=l,j=mid+1,p=l-1;
    while(i<=mid&&j<=r) {
        if(a[i]<=a[j]) b[++p]=a[i],i++;
        else b[++p]=a[j],j++,ans+=mid+1-i;
    }
    while(j<=r) b[++p]=a[j],j++;
    while(i<=mid) b[++p]=a[i],i++;
    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);
    }
    merge(1,n);
    printf("%d\n",ans);
    return 0;
}
posted @ 2017-10-24 21:26  zzzzx  阅读(143)  评论(0编辑  收藏  举报