Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 20404 Accepted Submission(s): 12231

Problem 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

思路:先求出原序列的逆序对和,在递推求变换位置的和,取最小值,用线段树叶子维护0~n-1的值

#include <cstdio>
#include <iostream>
#include <algorithm> using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=5000+100;
int sum[maxn<<2];
void pushup(int rt) {
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt) {
sum[rt]=0;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);//no need pushup all 0
} void update(int p,int l,int r,int rt) {
if(l==r) {
sum[rt]=1;
return ;
}
int m=(l+r)>>1;
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)>>1;
int ans=0;
if(L<=m) ans+=query(L,R,lson);
if(R>m) ans+=query(L,R,rson);
return ans;
}
int a[maxn];
int main() {
// freopen("input.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF) {
int ans=0;
build(0,n-1,1);
for(int i=0;i<n;i++) {
scanf("%d",&a[i]);
ans+=query(a[i],n-1,0,n-1,1);
update(a[i],0,n-1,1);
}
int ret=ans;
for(int i=0;i<n;i++) {
ans+=n-a[i]-a[i]-1;
ret=min(ret,ans);
}
printf("%d\n",ret);
}
return 0;
}

hdu 1394 逆序对(nlgn+o(n) )的更多相关文章

  1. HDU 1394 逆序数 线段树单点跟新 | 暴力

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

  2. HDU 1394 (逆序数) Minimum Inversion Number

    原来求逆序数还可以用线段树,涨姿势了. 首先求出原始序列的逆序数,然后递推每一个序列的逆序数. #include <cstdio> #include <cstring> #in ...

  3. hdu 1394 逆序数(线段树)

    http://acm.hust.edu.cn/vjudge/problem/15764 http://blog.csdn.net/libin56842/article/details/8531117 ...

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

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

  5. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  6. 线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop

    Minimum Inversion Number HDU - 1394 求最小反转数,就是求最少的逆序对. 逆序对怎么求,就是先把所有的数都初始化为0,然后按照顺序放入数字,放入数字前查询从这个数往后 ...

  7. HDU 1394 树状数组求逆序对

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

  8. HDU 1394 线段树求逆序对

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

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

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

随机推荐

  1. 刷seed有感

    今天又把seed刷了一遍 昨天去了基佬他们公司.第一次去他们公司.米虫科技,在重庆算是一家中型公司吧. 他去公司加班写一个游戏的封面,第一次感觉ui的不给设计图真的很坑.一个页面所有东西 自己凭感觉写 ...

  2. Intellij Idea 解决字符乱码、设定颜色主题、字体

    1.写入字符编码设置 2.调整mintty 字体.主题

  3. Centos 7防火墙firewalld开放端口

    firewall-cmd --zone=/tcp --permanent 出现success表明添加成功 命令含义:--zone #作用域--add-port=80/tcp #添加端口,格式为:端口/ ...

  4. vscode 创建.net core项目初体验

    微软的virtual studio编辑器那是宇宙第一大编辑器,可惜就是太笨重,遇到性能差一些的电脑设备,简直无法快速的编辑项目. 而vs code编辑器轻便易用,想要编辑哪种项目,只需扩展插件就OK, ...

  5. Vue 插槽

    插槽的概念: 插槽的关键字slot,默认情况下,组件中的模板会覆盖组件中的原始内容(即自定义标签对内部的内容会不显示),解决办法就是使用插槽. 组件的原始内容: 即在vue实例范围之内,因此可以调用实 ...

  6. Vue混入

    Vue 混入 混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 数据对象合 ...

  7. js求最大值最小值

    比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用自带的sort()函数,代码如下: <html> <head> <meta charset=&qu ...

  8. jquery实现本地图片上传预览和限流处理

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  9. Java——重写

    重写面向对象编程的三大特征之一 1.子类重写了父类的方法,则使用子类创建的对象调用该方法时,调用的是重写后的方法,即子类中的方法 2.子类重写父类方法需满足以下条件: (1)方法名和参数列表: 子类重 ...

  10. uploadfy 图片/视频上传

    JS引入 <link href="../../Scripts/uploadify/uploadify.css" rel="stylesheet" /> ...