HDU 1394 Minimum Inversion Number (树状数组 && 规律 && 逆序数)
题意 : 有一个n个数的数列且元素都是0~n-1,问你将数列的其中某一个数及其前面的数全部置到后面这种操作中(比如3 2 1 0中选择第二个数倒置就产生1 0 3 2)能产生的最少的逆序数对是多少?
分析 : 首先铁定排除枚举法,直接暴力肯定是超时的。既然这样不妨来找找规律,从第一个数开始,如果我们将第一个数放到末尾,根据逆序数的特点,能够推断出当前总逆序数应该是减少了arr[i]并增加了(n-1)-arr[i] (这里arr[i]代表这个数后面有多少个数小于它),如果细心一点,可以发现不管是从第几个数开始,都是由我们刚刚所说的将第一个数放到末尾构造而来,比如 1 2 3 4 我们将第二个数开始放到末尾就是 3 4 1 2,同样是可以这样构造而来,就是先将第一个数放到末尾产生一个序列 2 3 4 1,然后又进行一次将第一个数放到末尾产生3 4 1 2,这样根据我们之前得到的结论,只要知道当前序列的逆序数对和arr[i],我们就能递推出下一个序列的逆序数对。那么现在关键就是arr[i]怎么快速求?还记得序列是个0~n-1的序列嘛,实际上arr[i]就等于当前在头部的这个数的值,比如 2 1 3 0 在头部的是2,那么后面就有2个比它小的数!所以最终要得到答案我们只要一开始算出原始序列的逆序数对就能够O(n)的枚举了!
#include<bits/stdc++.h>
#define lowbit(i) (i&(-i))
using namespace std;
;
int c[maxn];
int top, n;
void add(int i, int val)
{
while(i <= n){
c[i] += val;
i += lowbit(i);
}
}
int sum(int i)
{
;
){
ret += c[i];
i -= lowbit(i);
}
return ret;
}
int arr[maxn];
int main(void)
{
while(~scanf("%d", &n)){
top = n;
memset(c, , sizeof(c));
memset(arr, 0x3f, sizeof(arr));
;
; i<n; i++){
int tmp;
scanf("%d", &arr[i]);
arr[i]+=;//树状数组小心0的陷阱!
SUM += i - sum(arr[i]);//累计求出初始序列的逆序数对
add(arr[i], );
}
int ans = SUM;
; i<n; i++){
ans = min(SUM, ans);
SUM += n - arr[i] - (arr[i] - );//递推构造
}
printf("%d\n", ans);
}
;
}
瞎 : 面对这种操作很明显有规律的,就要赶快先实验前几次操作,找找规律,再想想能不能递推,题目给出的序列的任何一个性质都是有用的,比如这里的0~n-1,以后遇到类似的题就把能得到的性质全部列出来,把每一步操作能得到的结果和特点综合分析,不能瞎想.....
HDU 1394 Minimum Inversion Number (树状数组 && 规律 && 逆序数)的更多相关文章
- HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number ...
- HDU 1394 Minimum Inversion Number (树状数组求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题目让你求一个数组,这个数组可以不断把最前面的元素移到最后,让你求其中某个数组中的逆序对最小是多 ...
- hdu 1394 Minimum Inversion Number - 树状数组
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...
- [hdu1394]Minimum Inversion Number(树状数组)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- hdu 5147 Sequence II (树状数组 求逆序数)
题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- poj 2299 Ultra-QuickSort(树状数组求逆序数)
链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...
- SGU180 Inversions(树状数组求逆序数)
题目: 思路:先离散化数据然后树状数组搞一下求逆序数. 离散化的方法:https://blog.csdn.net/gokou_ruri/article/details/7723378 自己对用树状数组 ...
随机推荐
- 【Qt开发】Qt应用程序发布封装
问题:在使用Qt5.3.2编写程序并release,文件夹中已经添加了必要的dll,但在其他机子上运行程序失败,出现了下面的情况: 解决方法一:在C:\Qt\Qt5.3.2\5.3中进入mingw48 ...
- java.time包常用类API学习记录
Java8出来已那么多年了,java.time包之前一直没有使用过,最近正好有用到,在此做个记录. 上图列出了java.time包下的类,接下来我们详细看下其中每个类的用法. Clock:获取到当前时 ...
- python 科学计数法转数值
猜测python应该是有现成的模块可以解决该问题,不过没找到,所以自己简单写了个函数处理: def tranform(inputString): num_value = re.compile('^[0 ...
- Java Content Repository API 简介 转自(https://www.ibm.com/developerworks/cn/java/j-jcr/)
Java Content Repository API 简介 1 如果曾经试过开发内容管理应用程序,那么您应当非常清楚在实现内容系统时所遇到的固有难题.这个领地有点支离破碎,许多供应商都有自己的私有仓 ...
- rebtree学习
http://www.cnblogs.com/skywang12345/p/3245399.html http://www.cnblogs.com/skywang12345/p/3624177.htm ...
- python——列表方法
L.append():追加一个元素到列表末尾 L = [] L.append('boy') L.insert() :将一个元素插入到指定位置 L.insert(1, 'girl') L.extend( ...
- cs244a-Introduction to Computer Networking-Unit2
Unit2: Transport 学习目标: how TCP set up a connection what TCP segment looks like how can TCP be in hig ...
- python:count 函数
API 一.string 中 某字符 的次数 str.count(sub, start= 0,end=len(string)) Args Annotations sub 搜索的子字符串 start 字 ...
- ActiveMQ利用ajax收发消息
准备工作: 后台需要导包: activemq-all.jar activemq-web.jar jetty-all.jar 如果是maven项目: pom.xml <dependency> ...
- OpenSSL使用小结
引言 互联网的发展史上,安全性一直是开发者们相当重视的一个主题,为了实现数据传输安全,我们需要保证:数据来源(非伪造请求).数据完整性(没有被人修改过).数据私密性(密文,无法直接读取)等.虽然现在已 ...