Minimum Inversion Number

http://acm.hdu.edu.cn/showproblem.php?pid=1394

题意:

n个数经过移动n个产生n个序列,每个序列都记录该序列中满足反转数的总个数,求这n个序列中最小的反转数的个数

思路:

这一题的关键是n-a[i]-(a[i]-1)这行代码

n-a[i]:第一个数字从第一个移到最后一个之后,其他n-1个数字他们增加反转数的个数

a[i]-1:移动之前这个数满足反转数的个数

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn = 5050;
int bit[maxn],a[maxn];
int n;
inline ll min(ll a,ll b){
    return a<b?a:b;
}
int lowbit(int x){
    return x&(-x);
}

ll sum(int x){
    ll ans=0;
    while(x){
        ans+=bit[x];
        x-=lowbit(x);
    }
    return ans;
} 

void query(int x){
    while(x<=n){
        bit[x]++;
        x+=lowbit(x);
    }
}

int main(){
    while(scanf("%d",&n)!=EOF){
        memset(bit,0,sizeof(bit));
        ll ans = 0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            a[i]++;
            ans += sum(n)-sum(a[i]);
            query(a[i]);
        }
        ll mm = ans;
        for(int i=1;i<=n;i++){
            mm +=n-a[i]-(a[i]-1);
            ans = min(ans,mm);
        }
        cout<<ans<<endl;
    } 
    return 0;
}

 

posted @ 2019-10-30 22:36  sqsq  阅读(94)  评论(0编辑  收藏  举报