hdu1394[树状数组,逆序对]

链接:hdu1394[树状数组,逆序对]

题解

  • 求出逆序数,O(N)遍历一遍
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define rep(i,x,y) for(register int i=x;i<=y;++i)
    #define repd(i,x,y) for(register int i=x;i>=y;--i)
    #define lowbit(x) x&(-x)
    using namespace std;
    const int N=1e5;
    const int inf=0x3f3f3f3f;
    typedef pair<int,int> s;
    int tr[N],a[N],n,res,ans;
    s q[N];
    inline void update(int x,int y){for(register int i=x;i<=n;i+=lowbit(i))tr[i]+=y;}
    inline int query(int x){int ans=0;for(register int i=x;i;i-=lowbit(i))ans+=tr[i];return ans;}
    int main(){
    while(~scanf("%d",&n)){
    ans=inf;res=0;
    memset(tr,0,sizeof(tr));
    rep(i,1,n){scanf("%d",&a[i]);q[i]=s(a[i],i);}
    sort(q+1,q+n+1);
    rep(i,1,n){update(q[i].second,1);res+=i-query(q[i].second);}
    if(ans>res)ans=res;
    rep(i,1,n){res=res-a[i]+n-a[i]-1;ans=min(ans,res);}
    printf("%d\n",ans);
    }
    return 0;
    }