POJ-2299-POJ 2299

来源:互联网 发布:手机淘宝信用等级查询 编辑:程序博客网 时间:2024/05/22 01:39

求对一列数排序所需的最少交换次数,也就是求逆序对个数

首先可以用归并排序做,比较简单

代码:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int maxn=500010;long long a[maxn],b[maxn],ans;int n;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,now=0;    while(i<=mid&&j<=R)    {if(a[i]>a[j]){    ans+=mid-i+1;    b[now++]=a[j++];}else    b[now++]=a[i++];    }    while(i<=mid)b[now++]=a[i++];    while(j<=R)b[now++]=a[j++];    now=0;    for(i=L;i<=R;i++)a[i]=b[now++];}int main(){    while(scanf("%d",&n)&&n)    {ans=0;for(int i=0;i<n;i++)    scanf("%lld",&a[i]);Merge(0,n-1);printf("%I64d\n",ans);    }    return 0;}
第二种方法是找逆序对的方法,用树状数组进行更新记录即可

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=500010;struct node{    long long val;    int index;    bool operator <(const node &a)const    {return val<a.val;    }}a[maxn];int n;long long c[maxn*3],index[maxn];int lowbit(int x){    return x&(-x);}void update(int x,int val){    for(int i=x;i<maxn*2;i+=lowbit(i))c[i]+=val;}long long sum(int x){    long long ans=0;    for(int i=x;i>0;ans+=c[i],i-=lowbit(i));    return ans;}int main(){    while(scanf("%d",&n)&&n)    {memset(c,0,sizeof(c));memset(index,0,sizeof(index));for(int i=1;i<=n;i++){    scanf("%I64d",&a[i].val);    a[i].index=i;}sort(a+1,a+n+1);index[a[1].index]=1;for(int i=2;i<=n;i++){    if(a[i].val!=a[i-1].val)index[a[i].index]=i;    elseindex[a[i].index]=index[a[i-1].index];}long long ans=0;for(int i=1;i<=n;i++){    update(index[i],1);    ans+=sum(n)-sum(index[i]);}printf("%I64d\n",ans);    }    return 0;}


原创粉丝点击