HDU 1394 Minimum Inversion Number 树状数组

来源:互联网 发布:巴蒂尔数据 编辑:程序博客网 时间:2024/05/15 21:09

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

101 3 6 9 0 8 5 7 4 2

Sample Output

16

这题就是找规律,因为第一种情况的值是依次插入,并寻找后面的比他小的且未被取到的点的个数和就行,求出第一种情况的值之后,之后的情况的值就是前一种情况加上比那移到后面的一点大的点的个数再减去比后面一点小的点的个数,这样依次类推找最小值就行。

#include <stdio.h>#include <string.h>const int n=5000;int c[n+10];int a[n+10];int lowbit(int k)  {      return (k&(-k));  }int sum(int x)  //求和{      int ret = 0;      while(x>0)      {          ret+=c[x];          x-=lowbit(x);      }      return ret;  }  void add(int x,int d)  //修改节点的值{      while(x<=n)      {          c[x]+=d;          x+=lowbit(x);      }  }int main(){int t;while(~scanf("%d",&t)){memset(a,0,sizeof(a));int i,j;for(i=0;i<t;i++){scanf("%d",&a[i]);a[i]=a[i]+1;}int min=0x3f3f3f3f;int pre=0;memset(c,0,sizeof(c));for(i=0;i<t;i++){pre+=a[i]-1-sum(a[i]-1);add(a[i],1);}min=pre;for(i=0;i<t-1;i++){pre+=t-a[i]-(a[i]-1);if(pre<min)min=pre;}printf("%d\n",min);}return 0;}


1 0
原创粉丝点击