Minimum Inversion Number  

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
题目大意就是给你 N 个区间,里面包含有0~N-1的整数,允许你每次将序列的头调到序列尾,让你求出最小的逆序和,
思路:先用线段树or树状数组预处理出原先的逆序和,然后再一个一个推出,每次操作后所产生的的新的逆序和,就拿样例来说,一开始的逆序和是22,如果将1调到末尾那里的话,原先在1后面比1小的数有1个,这个数是0,而当1调到后面的时候,在1前面的比一大的数有8个,为3,6,9,8,5,7,4,2,那么新序列的逆序和为22 - 1 + 8 = 29。以此类推
 
AC代码:线段树的方法,借鉴了notonlysuccess大神的姿势:
Memory: 320 KB   Time: 78 MS
#include <cstdio>
#include <iostream>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = ;
int sum[maxn<<];
void PushUp(int rt){
sum[rt] = sum[rt<<] + sum[rt<<|];
}
void build(int l,int r,int rt){
sum[rt] = ;
if(l == r) return ;
int m = (l + r) >> ;
build(lson);
build(rson);
return ;
}
void update(int p,int l,int r,int rt){
if(l == r){
sum[rt]++;
return ;
}
int m = (l + r)>>;
if(p <= m) update(p,lson);
else update(p,rson);
PushUp(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L <= l&&r <= R){
return sum[rt];
}
int m = (l + r)>>;
int ret = ;
if(L <= m) ret += query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret;
}
int x[maxn];
int main(){
int n;
while(~scanf("%d",&n)){
build(,n - ,);
int sum = ;
for(int i = ;i < n;i++){
scanf("%d",&x[i]);
sum += query(x[i],n - ,,n - ,);
update(x[i],,n - ,);
}
int res = sum;
for(int i = ;i < n;i++){
sum += n - x[i] - x[i] - ;
res = min(res,sum);
}
printf("%d\n",res);
}
return ;
}

后来我有用树状数组做了一下,发觉树状数组一般都要比线段树要快~

Memory: 332 KB   Time: 31 MS
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = ;
int c[maxn];
int a[maxn];
int n;
inline int lowbit(int x){
return x&(-x);
}
int sum(int x){
int ret = ;
while(x > ){
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(){
while(~scanf("%d",&n)){
memset(c,,sizeof(c));
memset(a,,sizeof(a));
int ans = ;
for(int i = ;i <= n;i++){
scanf("%d",&a[i]);
ans += i - - sum(a[i]);
add(a[i] + ,);
}
//cout<<ans<<endl;
int MIN = ans;
for(int i = ;i <= n;i++){
MIN += n - (a[i] + ) - (a[i]);
ans = min(MIN,ans);
}
printf("%d\n",ans);
}
return ;
}

HDU 1394 线段树or 树状数组~的更多相关文章

  1. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  2. HDU 1394 Minimum Inversion Number (树状数组求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题目让你求一个数组,这个数组可以不断把最前面的元素移到最后,让你求其中某个数组中的逆序对最小是多 ...

  3. HDU 1166 敌兵布阵 (数状数组,或线段树)

    题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...

  4. HDU 1394 Minimum Inversion Number (树状数组 && 规律 && 逆序数)

    题意 : 有一个n个数的数列且元素都是0~n-1,问你将数列的其中某一个数及其前面的数全部置到后面这种操作中(比如3 2 1 0中选择第二个数倒置就产生1 0 3 2)能产生的最少的逆序数对是多少? ...

  5. hdu 1394 线段树

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  6. HDU 2492 Ping pong (数状数组)

    Ping pong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. hdu 1394 Minimum Inversion Number - 树状数组

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  8. hdu 1394(线段树) 最小逆序数

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 给出一列数组,数组里的数都是从0到n-1的,在依次把第一个数放到最后一位的过程中求最小的逆序数 线段树的应 ...

  9. hdu 1394 线段树计算逆序数

    线段树计算逆序数的原理: 用线段树来统计已插入的数的个数(所以要保证最大的那个数不能太大,否则数组都开不了),然后每插入一个数,就查询比插入的数大的个数,累加即可. 这个题还有一个特点就是,题目给的是 ...

随机推荐

  1. mysql出现问题汇总(持续更新)

    1.mysql -uqwe -p普通用户登陆时提示: ERROR 1045 (28000): Access denied for user 'baijie'@'%' (using password: ...

  2. [转]Delphi调用cmd并取得输出文本

    //转自http://www.oschina.net/code/snippet_136241_3980 1 procedure CheckResult(b: Boolean); begin if no ...

  3. SVN CommandLine

    要是SVN命令行用不了的话: 1.SVN装了没? 2.SVN安装时,选项“command line client tools”选了没. 检出: svn checkout [-depth ARG] [- ...

  4. buf.slice()

    buf.slice([start[, end]]) start {Number} 默认:0 end {Number} 默认:buffer.length 返回:{Buffer} 返回一个指向相同原始内存 ...

  5. Web的三大基石

    [HTML] 实现了Web页面. [URL] 1.url Uniform Resource Locator的缩写,称为统一资源定位符.通过URL可以访问到互联网上的一个资源.如:图片.视频.网页等.通 ...

  6. java中检测-在运行时指定对象是否是特定类的一个实例---关键字 instanceof

    java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. if(requ ...

  7. csu - 1538: Shopping (贪心)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1538 很奇妙的一个题,开始没有思路.问了别人才知道. 题目的意思可以理解成上图中,从0点开始向右走 ...

  8. Codeforces 404D Minesweeper 1D

    题意: 给定字符串,其中'*'表示地雷,'1'表示左/右边有一个地雷相邻,'2'表示左右两边均有地雷相邻,'0'表示左右均无地雷相邻,'?'表示待定,可填入0,1,2或者地雷,有多少种表示方法使字母串 ...

  9. Servlet开发(1)

    Servlet开发 Servlet引入: 百度百科详细servlet介绍: 重点概括:servlet运行在服务器上,处理用户请求. 我们使用response来获取一个写方法 PrintWriter o ...

  10. Linux简单口令

    创建文件1.touch2.echo "">>file_name3.vim 文件名创建文件夹1.mkdir -p /abc/cc/bbb删除文件rm -f 文件删除文件夹 ...