线段树---HDU1394Minimum Inversion Number
此题和上题略有不同,但是大体差不多,不过要把题意转换过来,题目大体意思为, 输入n, 也就是n个数,这些数为0 - (n-1), 这些数刚开始给定输入的顺序, 然后求他的逆序数,然后接着把第一个移到这个数列的末尾,这时候再求出一个逆序数,直到移动一个周期,也就是移动了n次, 求他们之中的最小的一个逆序数。
大体思路:
1. 首先建立线段树,初始化每个节点的值都为0
2. 输入原序列的同时,将原序列的逆序数求出来
其中这个求的过程为找到它导致的逆序数为多少,就是找在它之前有多少个比它大的
3. 遍历一遍, 然后将剩下的n - 1 个序列的逆序数求出来,其中这里有个公式, 可以推导出来,就是可以这么考虑,假设这是第一次将第一个数移到数组的末尾,假设这个数为X[i], 它所导致的 整个数组的逆序数的变化为: 首先,它造成他后面数的逆序数为X[i](这里的X[i]就是它本身), 这个是当前数组中把它去掉之后减少的逆序数, 所以去掉它之后整个数组的逆序数就是 Sum - x[i](这里Sum就是总的逆序数), 然后把它加到最后,它可以增加的逆序数就为 n - 1 - x[i], 所以变化这一次当前数组的逆序数为 Sum - x[i] + n - 1 - x[i]; 这个可以这么求公式,是因 为这个题特殊, 因为数组里面的数为从0 - n-1, 而且还没有重复的。
下面是代码的实现:
#include <cstdio>
#include <algorithm> using namespace std; const int MAX = * ;
int sum[MAX];
//更新跟其有关的以上所有节点
void pushUp(int root)
{
sum[root] = sum[root * ] + sum[root * + ];
} void buildTree(int root, int left, int right)
{
sum[root] = ;//初始化
if(left == right)
{
return;
}
int mid = (left + right) / ;
buildTree(root * , left, mid);
buildTree(root * + , mid + , right);
//pushUp(root);//这里可以不需要, 因为初始化都是0
} void update(int root, int pos, int left, int right)
{
if(left == right)
{
sum[root]++;
return;
}
int mid = (left + right) / ;
if(pos <= mid)
update(root * , pos, left, mid);
else
update(root * + , pos, mid + , right);
pushUp(root);
}
//L, R代表要寻找的区间, left和right代表当前区间
int getSum(int root, int L, int R, int left, int right)
{
/*找大于L的, 因为大于L才能导致逆序数, 所以找它之前所有大于L的,
即在线段上区间可以这么写 */
if(L <= left && R >= right)
{
return sum[root];
}
int mid = (left + right) / ;
int res = ;
if(L <= mid)
{
res += getSum(root * , L, R, left, mid);
}
if(R > mid)
{
res += getSum(root * + , L, R, mid + , right);
}
return res;
} int main()
{
int x[MAX];
int n;
while(~scanf("%d", &n))
{
buildTree(, , n - );
int Sum = ;
for(int i = ; i < n; i++)
{
scanf("%d", &x[i]);
//获得当前数导致的逆序数
Sum += getSum(, x[i], n - , , n - );
update(, x[i], , n - );
}
int t = Sum;
for(int i = ; i < n; i++)
{
//此公式是由 Sum = Sum - x[i] + n - 1 - x[i]的变形
Sum += n - x[i] - x[i] - ;
t = min(Sum, t);
}
printf("%d\n", t);
} return ;
}
线段树---HDU1394Minimum Inversion Number的更多相关文章
- hdu1394--Minimum Inversion Number(线段树求逆序数,纯为练习)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- hdu1394Minimum Inversion Number(线段树,求最小逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu1394Minimum Inversion Number
Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...
- HDU1394-Minimum Inversion Number
http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Time Limit: 2000/1000 MS (Ja ...
- C++-HDU1394-Minimum Inversion Number[数据结构][树状数组]
给出0~n-1的一个排列,可以整体移动,求逆序对最小值 把数字num[i]的加入,等价于树状数组的第n-num[i]位加1 因为num[i]是第 (n-1)-num[i]+1=n-num[i]大的数字 ...
- 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)
转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
- HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)
题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS Memory Limit: 32768 K Description The inve ...
- ACM Minimum Inversion Number 解题报告 -线段树
C - Minimum Inversion Number Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &a ...
随机推荐
- Git对于单个文件的分批提交方式的使用
很多时候,对于一个大的文件,可能有的同学改完之后不想一次提交,想分批提交.但这个时候由于git add的机制往往add之后就是整个一个文件被放到stage区了,这个时候肯定会想能不能对一个文件可以进行 ...
- Java中的继承与组合
本文主要说明Java中继承与组合的概念,以及它们之间的联系与区别.首先文章会给出一小段代码示例,用于展示到底什么是继承.然后演示如何通过“组合”来改进这种继承的设计机制.最后总结这两者的应用场景,即到 ...
- 让 zend studio 识别 Phalcon语法并且进行语法提示
让 zend studio 识别 Phalcon语法并且进行语法提示 https://github.com/phalcon/phalcon-devtools/tree/master/ide 下载解压 ...
- C++的类为什么要用指针
这个问题原来是这样的: C++的对象和C#不同,C++的对象是放在栈区的,C#的对象是引用类型. 这就意味着,C++进行类型转换的时候,由于调用了复制构造函数,其转换后,对象会丢弃一部分信息. 派生类 ...
- iOS常见内存泄漏解决
iOS常见内存泄漏解决 1 OC和CF转化出现的内存警告 CFStringRef cfString = CFURLCreateStringByAddingPercentEscapes(kCFA ...
- Python实现ID3算法
自己用Python写的数据挖掘中的ID3算法,现在觉得Python是实现算法的最好工具: 先贴出ID3算法的介绍地址http://wenku.baidu.com/view/cddddaed0975f4 ...
- cf C. Divisible by Seven
http://codeforces.com/contest/376/problem/C 题意:给你一个大数最多含有10^6个数字,这里面必须含有1,6,8,9,然后重新排列找出一个能被6整除的数. 思 ...
- C#程序设计基础——变量
变量表示数值,字符串值或类的对象.变量存储的值可能会发生更改,但名称保持不变.C#是一种强类型语言,在变量中存储值之前,必须指定变量的类型. 变量的命名规则: 1-变量只能有字母,数字和下划线三种字符 ...
- ISO14443标准详细介绍
这篇文章从各方面详细介绍了ISO/IEC14443标准.第一部分:物理特性1.范围ISO/IEC14443的这一部分规定了邻近卡(PICC)的物理特性.它应用于在耦合设备附近操作的ID-1型识别卡.I ...
- JavaScript权威指南学习笔记5
下午在杭图回去前看了书中第二部分的13-17章,看的很粗,感觉大部分东西自己已经知道或者平时开发中不会用到,很多章节只是简单的翻了一下,没有仔细思考里面说到的道理,下面对各章节简单的记录下. 第13章 ...