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

 
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.

 

给定一个数组 a1,a2....an,定义逆序数对(i,j)满足条件 i< j 且 ai > aj。
现在题目给你数组,求他的所有循环数组的逆序数对中最少的是多少。
所谓循环数组即为:

a1, a2, ..., an-1, an (从1开始的初始数组) 
a2, a3, ..., an, a1 (从a2开始到an,再加上a1) 
a3, a4, ..., an, a1, a2 (a3开始到an,再连上a1和a2) 
... 
an, a1, a2, ..., an-1 (an,然后从a1到a(n-1))

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.
 

输入有多组数据. 每个测试案例的第一行是一个数n(n <= 5000)表示数组长度: 接下来一行是n个数表示数组内容,数组内的数字是0~n-1以内的数,且没有重复

Output
For each case, output the minimum inversion number on a single line.
对于每个样例输出一个数字表示答案 
 

思路:

首先是怎么求其中一个序列的逆序数对
假设序列开始一个数都没有
每添加一个数之前计算序列有多少数大于该数(即在该位添加时会增加多少对逆序数)<===算作一个状态
将所有状态相加即是该序列的逆序数对数量
拿样例来说
 
 
那怎么高效的算出所有循环数组的逆序数对个数
观察不难发现,当a0移动到an-1末尾后减少了它之后能与它形成逆序数对的个数(比它小的数)
                                               增加了在末尾时它之前能与它形成逆序数对的个数(比它大的数)
由于下一个循环数列必定是将头移至尾,所以减少的个数为比它小的个数
                                                                        增加的个数为比它大的个数
因为数是不会重复的且为0~n-1共n个,所以 a[i] - 1就是序列中比它小的数的个数
                                                                      n - a[i]就是序列中比它大的数的个数
 

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = ; int c[maxn], a[maxn], n; inline int lowbit(int x){
return x&(-x);
} void update(int i, int value){
while(i <= n){
c[i] += value;
i += lowbit(i);
}
} int sum(int i){
int s = ;
while(i > ){
s += c[i];
i -= lowbit(i);
}
return s;
} int main(){
while(~scanf("%d", &n)){
for (int i = ; i <= n; ++i){
c[i] = ;
}
int s = ; //最开始逆序数对数为0
for(int i = ; i <= n; i ++){
scanf("%d", &a[i]);
a[i] ++; //树状数组从1开始 数据范围(0~n-1)
s += (sum(n) - sum(a[i])); //找出所有比a[i]大的数的逆序数对数
update(a[i], ); //记录这个数
}
int ans = s;
for(int i = ; i < n; i ++){
s += (n - a[i]* + ); //比较完后因为 n 个数范围(0~n-1)且不重复, 所以比a[i] 小的数为a[i] - 1;
// 每次将头元素移至末尾都会减少比头小的数(a[i] - 1)个逆序数,增加比头大的数(n - a[i])个逆序数
// 所以增加的逆序数为 n - a[i] * 2 + 1 [+(n - a[i]) -(a[i] - 1)]
if(ans > s) //记录更少的逆序数对数
ans = s;
}
printf("%d\n", ans);
}
return ;
}
 

hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)的更多相关文章

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

    Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showprob ...

  2. HDU 1394 Minimum Inversion Number (数据结构-段树)

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

  3. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

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

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

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

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

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

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

  7. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

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

  8. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

  9. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

随机推荐

  1. Markdown学习使用

    本文记录Markdown的基础应用. 一.基础知识 Markdown 是一种标记语言 文件后缀名:.md 编辑工具:VSCode(visual studio code) VSCode中预览模式快捷键: ...

  2. Spark Worker原理和源码剖析解密:Worker工作流程图、Worker启动Driver源码解密、Worker启动Executor源码解密等

    本课主题 Spark Worker 原理 Worker 启动 Driver 源码鉴赏 Worker 启动 Executor 源码鉴赏 Worker 与 Master 的交互关系 Spark Worke ...

  3. OC基础数据类型-NSArray

    1.数组的初始化 NSArray *array = [[NSArray alloc] initWithObjects:@"One", @"Two", @&quo ...

  4. 022configparser模块

    #配置模块 #创建import  configparser config  =  configparser.ConfigParser() #添加config["DEFAULT"]  ...

  5. AngularJs学习笔记--Dependency Injection(DI,依赖注入)

    原版地址:http://code.angularjs.org/1.0.2/docs/guide/di 一.Dependency Injection(依赖注入) 依赖注入(DI)是一个软件设计模式,处理 ...

  6. Webpack笔记(二)——搭建React开发环境

    前几天一直在学习webpack,总算比之前学习的时候有了点收获,所以在昨天发布了一篇webpack入门笔记,今天继续使用webpack练了练手,搭建了一个React开发环境,如果还不熟悉的童鞋可以看一 ...

  7. postgresql+postgis+pgrouting实现最短路径查询(3)--流程图

    项目结束,做一个项目的总结汇报,就把最短路径查询的实现流程图画了一下,现在补出来:

  8. SSH2整合需要jar包解释

    hibernate3.jar, Hibernate的库,必须使用的jar包 antlr-2.7.6.jar, 语法分析生成器 语言转换工具,hibernate利用它实现HQL到SQL的转换 cglib ...

  9. 一些jar包的作用

    发项目的过程中,经常需要用到一写jar包,现在对其中的一写jar的作用,做下总结,也算是避免少引或者多引jar包吧,欢迎大家补充.谢谢. 1.apache的一写jar commons-collecti ...

  10. 五·管理mysql

    在上一篇文章中 四·安装mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz(基于Centos7源码安装) 已经安装好了mysql,也正常启动了.本篇文章主要内容是管理m ...