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. SharePoint 2013 - REST API about Security

    1. 获取当前用户信息(current user): var currentUserInfo = "{0}/_api/Web/CurrentUser"; // {0} -> ...

  2. 【 Oral English】Pronunciation

    一.英语音素 1.元音(元首,主要部分) 特点: a.无阻碍,拖很长认可辨别 b.声音响亮 2.辅音(重点,刻意练习) 特点: a.刻意阻碍 b.短促 二.汉语元素 1.音节:最小组成成分,而非元/辅 ...

  3. Raspberry U盘操作

    项目系统要求的对U盘分区,分出系统盘与用户盘.这就有了今天的这个总结了: 1.输入命令“fdisk -l”查看设备挂载的位置,因为这个在设备挂载的时候有可能会发生变化. 假设设备挂载到了 /dev/s ...

  4. Electron在Windows下的环境搭建

    Electron作为一种用javascript写桌面程序的开发方式,现在已经被大众接受.下面就介绍如何在windows(>win7)下快速搭建Electron开发环境. 1. nodejs 的安 ...

  5. 【转】iOS lame编译 arm64 armv7s armv7 x86_64 i386指令集

    原文出至 http://blog.csdn.net/vieri_ch/article/details/40650467 最近升级了系统到Mac OS X 10.10 并且更新了XCode6.1和iOS ...

  6. QT 编译遇到重定义;不同的基类型&在QT中使用C++ lib库

    最近在使用osg和qt开发,在集成osg时候因为我使用的qt版本为非opengl的版本,导致qt自己封了一遍opengl的一些基类变量如double 这时候就会跟osg中声明的opengl的类型冲突, ...

  7. 64位Navicat Premium-11.2.7(64bit)访问64位Oracle服务器

    1 在windows 10 64位操作系统安装Navicat Premium-11.2.7(64bit). 2 在服务器安装64位的Oracle(win64_11gR2_database). 3 在h ...

  8. css tips: 清除float影响,containing的div跟随floated sub等

    /** * For modern browsers * 1. The space content is one way to avoid an Opera bug when the * content ...

  9. Azure DocumentDB 正式发布

    DocumentDB 简介 一种 NoSQL JSON 数据库 Azure DocumentDB 提供完全托管的 NoSQL 数据库服务,高度可用,自动缩放,开发简易,可以加速并预测性能.它适合诸如 ...

  10. Linux-->Mysql:安装,测试

    环境准备 mysql下载地址:https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-linux-glibc2.12-x86_64.tar ...