码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-04-06 23:00:48      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

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;
    }
}

 

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

标签:

原文地址:http://www.cnblogs.com/qscqesze/p/4396831.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!