HDU 1394 Minimum Inversion Number

题目大意:

求Inversion后的最小逆序数。


解题思路:

用O(nlogn)复杂度求出最初逆序数后,就可以用O(1)的复杂度分别递推出其他解。

线段树维护,比当前叶子节点小的叶子节点个数。

写了一份暴力,一份线段树,线段树的效率大概是暴力的八倍以上。


暴力

#include<cstdio>
int a[5555];
int main()
{
    int n,i,j,ans=999999999;
    while(scanf("%d",&n)!=EOF)
    {
        ans=999999999;
           for(i=0;i<n;i++) scanf("%d",&a[i]);
           int cnt=0;
           for(i=0;i<n;i++)
               for(j=i+1;j<n;j++)
               {
                   if(a[i]>a[j]) cnt++;
               }
           // printf("cnt=%d\n",cnt);
           if(ans>cnt)  ans=cnt;
           for(i=0;i<n;i++)
           {
               cnt=cnt-a[i]+n-1-a[i];
               if(ans>cnt)  ans=cnt;
            }
           printf("%d\n",ans);
    }
    return 0;
}


线段树

#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 5555
using namespace std;
int sum[maxn<<2];
int max(int x,int y){
    if (x>y) return x;
    else return y;
}
int min(int x,int y){
    if (x<y) return x;
    else return y;
}
void PushUP(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt){
    sum[rt]=0;
    if (l==r) return ;
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
}
void update(int p,int l,int r,int rt){
    if (l==r) {
        sum[rt]++;
        return ;
    }
    int mid=(l+r)>>1;
    if (p<=mid) update(p,l,mid,rt<<1);
    else update(p,mid+1,r,rt<<1|1);
    PushUP(rt);
}
int query(int L,int R,int l,int r,int rt){
    if (L<=l && r<=R) {
        return sum[rt];
    }
    int mid=(l+r)>>1;
    int ret=0;
    if (L<=mid) ret+=query(L,R,l,mid,rt<<1);
    if (R>=mid) ret+=query(L,R,mid+1,r,rt<<1|1);
    return ret;
}
int x[maxn];
int main(){
    int n;
    while (~scanf("%d",&n)){
        build(0,n-1,1);
        int sum=0;
        for (int i=0;i<n;i++){
            scanf("%d",&x[i]);
            sum+=query(x[i],n-1,0,n-1,1);
            update(x[i],0,n-1,1);
        }
        int ret=sum;
        for (int i=0;i<n;i++){
            sum+=n-x[i]-x[i]-1;
            ret=min(ret,sum);
        }
        printf("%d\n",ret);
    }
    return 0;
}


你可能感兴趣的:(HDU 1394 Minimum Inversion Number)