HDU - 1394 Minimum Inversion Number (线段树求逆序数)
Description
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.
Input
Output
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
题意:每次能够将第一个放到最后一个,求这个过程中最小的逆序数和
思路:线段树的点更新,首先读入序列的时候就能够算出一个逆序数,找找比它大的数的个数,
之后将第一个a[0]放到最后一个的时候,每次降低的是a[0],添加的是(n-a[0]-1)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1)
using namespace std;
const int MAXN = 5005;
const int ROOT = 1;
const int inf = 0x3f3f3f3f;
// single point updated
struct seg{
int w;
}; struct segment_tree {
seg node[MAXN * 4]; void update(int pos) {
node[pos].w = node[lson(pos)].w + node[rson(pos)].w;
} void build(int l, int r, int pos) {
if (l == r) { node[pos].w = 0; return; }
int m = l + r >> 1;
build(l, m, lson(pos));
build(m + 1, r, rson(pos));
update(pos);
} void modify(int l, int r, int pos, int x, int y) {
if (l == r) { node[pos].w = 1; return; }
int m = l + r >> 1;
if (x <= m) modify(l, m, lson(pos), x, y);
else modify(m + 1, r, rson(pos), x, y);
update(pos);
} int query(int l, int r, int pos, int x, int y) {
if (x <= l && r <= y) return node[pos].w;
int m = l + r >> 1;
int res = 0;
if (x <= m) res += query(l, m, lson(pos), x, y);
if (y > m) res += query(m + 1, r, rson(pos), x, y);
return res;
} int remove(int l, int r, int pos, int x) {
if (l == r) { node[pos].w = 0; return l; }
int m = l + r >> 1;
int res;
if (x < node[lson(pos)].w) res = remove(l, m, lson(pos), x);
else res= remove(m + 1, r, rson(pos), x - node[lson(pos)].w);
update(pos);
return res;
}
} tree; int main() {
int n;
int a[MAXN];
while (scanf("%d", &n) != EOF) {
tree.build(1, n, 1);
int cnt = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
cnt += tree.query(1, n, 1, a[i]+1, n);
tree.modify(1, n, 1, a[i]+1, 1);
}
int ans = cnt;
for (int i = 0; i < n-1; i++) {
cnt += (n - 2*a[i] - 1);
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
return 0;
}
HDU - 1394 Minimum Inversion Number (线段树求逆序数)的更多相关文章
- [HDU] 1394 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 (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- hdu - 1394 Minimum Inversion Number(线段树水题)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
- HDU 1394 Minimum Inversion Number 线段树
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...
- HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...
- HDU_1394_Minimum Inversion Number_线段树求逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu 13394 Minimum Inversion Number 线段树
题意: 首先给你一个长度为n的序列v,你需要首先找出来逆序对(i<j && v[i]>v[j]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...
- hdu 1394 Minimum Inversion Number (树状数组求逆序对)
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...
- HDU 1394 Minimum Inversion Number (树状数组)
题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...
- HDU 1394 Minimum Inversion Number(树状数组/归并排序实现
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- 基于Velocity开发自己的模板引擎
Velocity是一个基于java的模板引擎(template engine).它同意不论什么人只简单的使用模板语言(template language)来引用由java代码定义的对象. 当Veloc ...
- HYSBZ 2243 染色 (树链拆分)
主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...
- OpenCV+MFC显示图像
1.首先下载openCV. 2.安装OpenCV.现在的版本号2.4.9,你并不需要配置环境变量. 3.设置包括文件夹,设定project库文件夹. 4.配置链接库.注意,链接库包含了文件名中包含一个 ...
- 【C语言探索之旅】 第二部分第六课:创建你自己的变量类型
内容简介 1.课程大纲 2.第二部分第六课: 创建你自己的变量类型 3.第二部分第七课预告: 文件读写 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C ...
- 无需Visual Studio,5容易的 - 分为报告
总报告设计,例如RDLC.水晶报表等.,需要安装Visual Studio.由VS提供报表设计界面设计报告,由VS设计报告.NET非常方便开发者,.但对于非开发,安装4G一个VS.并且需要Licens ...
- SQL 2008执行语句遇到内存不足(1)——error 701
原文:SQL 2008执行语句遇到内存不足(1)--error 701 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/01/17/sql-2008-e ...
- 据序和中序序列或者也许为了一个二进制序列,恢复二进制和打印图像(c语言)
首先要预购和序,以恢复它: 1.首先,我们使用的是递归的方式来完成 2.递归的最小单位:一个空的树和书的前言和第一序.该序列的第一个元素是树的第一序列根,调用这种方法 3.递归的终止条件是.当这棵树的 ...
- Android SystemUI源代码分析和修改
1.在导航栏中添加音量加减button 一些Android音量调节button.或者从保护实体按键的角度考虑,就须要在导航栏的虚拟按键中加入音量加减调节按键. 效果例如以下图所看到的: 实现步骤例如以 ...
- 使用python+flask让你自己api(教程源代码)
1.背景 ok,这可能是很多朋友和我一样经常使用的各种api,例facebook的.github的.甚至微信api.因此,很多人都想使自己的api.在线教程在这方面它是非常小的,今天,我做了一个平稳, ...
- HDOJ 3480 Division
斜率优化DP. ... 对数组排序后.dp[i][j]表示对前j个物品分i段的最少代价,dp[i][j]= min{ dp[i-1][k]+(a[k+1]-a[j])^2 }复杂度m*n^2 ...