title

逆序对

1、树状数组+离散化(nlogn)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#define int long long
using namespace std;
const int N = 40010;
struct node {
	int v,order;
};
int n,aa[N],c[N];
node a[N];
inline int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch))	f|=(ch=='-'),ch=getchar();
	while(isdigit(ch))	x=x*10+(ch^48),ch=getchar();
	return f?-x:x;
}
inline int lowbit(int x){
	return x & -x;
}
inline void add(int x,int val){
	for(;x<=n;x+=lowbit(x)){
		c[x]+=val;
	}
}
inline int getsum(int x){
	int ans=0;
	for(;x;x-=lowbit(x)){
		ans+=c[x];
	}
	return ans;
}
inline bool cmp(node a,node b){
	return a.v<b.v;
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		a[i].v=read();
		a[i].order=i;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;++i){
		aa[a[i].order]=i;
	}
	int ans=0;
	for(int i=1;i<=n;++i){
		add(aa[i],1);
		ans+=i-getsum(aa[i]);
	}
	printf("%lld",ans);
	return 0;
}

2、归并排序(nlogn)

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#define N 40010
using namespace std;
int a[N],f[N],ans,n;
inline int read()
{
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
inline 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;
	while(i<=mid&&j<=r){
		if(a[i]>a[j]){
			f[p++]=a[j++];
			ans+=mid-i+1;
		} else f[p++]=a[i++];
	} 
	while(i<=mid)	f[p++]=a[i++];
	while(j<=r)		f[p++]=a[j++];
	for(int i=l;i<=r;i++)	a[i]=f[i];
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++)	a[i]=read();
	merge(1,n);
	printf("%d",ans);
	return 0;
}
posted @ 2018-09-10 01:13  Horrigue_JyowYang  阅读(79)  评论(0编辑  收藏  举报