求逆序对
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int a[N];
int n,t;
ll merge_sort(int l,int r)
{
if(l>=r) return 0;
int mid=r+l>>1;
ll k=merge_sort(l,mid)+merge_sort(mid+1,r);
int b[N],cnt=0;
int ll=l,rr=mid+1;
while(ll<=mid&&rr<=r)
{
if(a[ll]<=a[rr]) b[++cnt]=a[ll++];
else
{
k+=mid-ll+1;
b[++cnt]=a[rr++];
}
}
while(ll<=mid) b[++cnt]=a[ll++];
while(rr<=mid) b[++cnt]=a[rr++];
for(int i=l;i<=r;i++) a[i]=b[i-l+1];
return k;
}
int main()
{
while(~scanf("%d",&n))
{
if(n==0) break;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
ll ans=merge_sort(1,n);
printf("%lld\n",ans);
}
}
两处错误:
1.while(rr<=mid) b[++cnt]=a[rr++];
2.每次函数都会开一个b[N]需要空间太大
正解
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int a[N],b[N];
int n,t;
ll merge_sort(int l,int r)
{
if(l>=r) return 0;
int mid=r+l>>1;
ll k=merge_sort(l,mid)+merge_sort(mid+1,r);
//int b[N],cnt=0;
int cnt=0;
int ll=l,rr=mid+1;
while(ll<=mid&&rr<=r)
{
if(a[ll]<=a[rr]) b[++cnt]=a[ll++];
else
{
k+=mid-ll+1;
b[++cnt]=a[rr++];
}
}
while(ll<=mid) b[++cnt]=a[ll++];
while(rr<=r) b[++cnt]=a[rr++];
for(int i=l;i<=r;i++) a[i]=b[i-l+1];
return k;
}
int main()
{
while(~scanf("%d",&n))
{
if(n==0) break;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
ll ans=merge_sort(1,n);
printf("%lld\n",ans);
}
}