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 自己对用树状数组 ...
随机推荐
- SSM004/工作内容
一.java执行sql脚本 参考博客:java调用SQL脚本执行的方案 1.Service层代码:目的随spring容器启动即执行 //Service层代码 @Component public cla ...
- [转帖]vCenter 计划任务.
vSphere5.0实用小技巧-DPM计划任务 2013年05月12日 23:00:09 weixin_34185320 阅读数:9 https://blog.csdn.net/weixin_3418 ...
- Linux 查看文件内容(8)
我们知道在图形界面上查看文件内容只需要双击打开就好,那么在终端窗口里怎么查看文件内容呢?显然是需要能有一个命令能把文件内容显示在终端界面上. 查看文件内容主要有两个命令,分别是 cat 和 more, ...
- 【7.9校内test】T1挖地雷
(土气的名字万里挑一丫丫) 然后这个题是个递推,lz的考场想法: 3个的最好确定,先把3个的确定下来,然后从这个点往前推,从这个点往后推这么算吧qwq 然后码长:也是很nice,最关键的是,我都写的这 ...
- springBoot2.0配置profile
1. 使用yaml来配置,直接配置application.yml文件 server: port: 8888 spring: profiles: active: dev # 激活生产环境 --- # 测 ...
- 26. Remove Duplicates from Sorted Array(代码思路新奇)
Given a sorted array, remove the duplicates in-place such that each element appear only once and ret ...
- ElasticSearch5.3安装IK分词器并验证
ElasticSearch5.3安装IK分词器 之前使用Elasticsearch安装head插件成功了,但是安装IK分词器却失败了.貌似是ElasticSearch5.0以后就不支持直接在elast ...
- Jmeter 设置默认语言为中文
1.在apache-jmeter-4.0\bin目录下,打开jmeter.properties; 2.将#language=en改为#language=cn,保存 3.重新启动jmeter.
- visual studio git 忽略文件配置模板
## Ignore Visual Studio temporary files, build results, and## files generated by popular Visual Stud ...
- k路归并
public static int[] k_merge(ArrayList<int[]> k_array) { if(CollectionUtils.isEmpty(k_array)){ ...