逆序对
关于逆序对的两种解法
其实归并排序似乎快一点
。。。
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;
}