hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

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

Description

The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.

Input

The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.

Output

For each case, output the minimum inversion number on a single line.

Sample Input

10
1 3 6 9 0 8 5 7 4 2

Sample Output

16

HINT

题意

 

这个区间可以变,就是可以把第一个数扔到最后去,然后这样变呀变,问这种变化下,最小的逆序数数是多少

 

题解:

 

啊,最大的数为n,把第一个数扔到最后,那么逆序数减少了num[i]-1,但是却增加了n-num[i],那就随便搞搞就好啦~  

 

代码:

 

//qscqesze

#include <cstdio>

#include <cmath>

#include <cstring>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <set>

#include <vector>

#include <sstream>

#include <queue>

#include <typeinfo>

#include <fstream>

#include <map>

typedef long long ll;

using namespace std;

//freopen("D.in","r",stdin);

//freopen("D.out","w",stdout);

#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)

#define maxn 100001

#define mod 10007

#define eps 1e-9

const int inf=0x7fffffff;   //无限大

/*

inline ll read()

{

    int x=0,f=1;char ch=getchar();

    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

*/

//**************************************************************************************

int d[maxn];

int c[maxn];

int n;

int t;

inline int read()

{

    int x=0,f=1;char ch=getchar();

    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}

    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

    return x*f;

}

int lowbit(int x)

{

    return x&-x;

}



void update(int x,int y)

{

    while(x<=t)

    {

        d[x]+=y;

        x+=lowbit(x);

    }

}

int sum(int x)

{

    int s=0;

    while(x>0)

    {

        s+=d[x];

        x-=lowbit(x);

    }

    return s;

}

int num[maxn];

int main()

{

    while(scanf("%d",&n)!=EOF)

    {

        memset(d,0,sizeof(d));

        memset(num,0,sizeof(num));

        memset(c,0,sizeof(c));

        //n=read();

        int ans=0;

        t=n;

        for(int i=0;i<n;i++)

        {

            num[i]=read();

            num[i]++;

            ans+=num[i]-sum(num[i]-1)-1;

            update(num[i],1);

        }

        int tmp=ans;

        for(int i=0;i<n;i++)

        {

            tmp+=n-1-2*num[i]+2;

            ans=min(tmp,ans);

        }

        cout<<ans<<endl;

    }

}

 

你可能感兴趣的:(version)