HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
ACM
题目地址:HDU 1394 Minimum Inversion Number
题意:
给一个序列由[1,N]构成。能够通过旋转把第一个移动到最后一个。
问旋转后最小的逆序数对。
分析:
注意,序列是由[1,N]构成的,我们模拟下旋转,总的逆序数对会有规律的变化。
求出初始的逆序数对再循环一遍即可了。
至于求逆序数对,我曾经用归并排序解过这道题:点这里。
只是因为数据范围是5000。所以全然能够用线段树或树状数组来做:求某个数的作为逆序数对的后面部分的对数,能够在前面的数中查询小于这个数的数的个数。
直接在线一边加一边查即可了,复杂度为O(nlogn)。
只是老实说,这题的单个数没有太大,不然线段树和树状数组都开不下的。所以求逆序数对的最佳算法应该是归并排序解。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: 1394_segment_tree.cpp
* Create Date: 2014-08-05 10:08:42
* Descripton: segment tree
*/ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define repf(i,a,b) for(int i=(a);i<=(b);i++) #define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1) typedef long long ll; const int N = 5010;
const int ROOT = 1; // below is sement point updated
struct seg {
ll w;
}; struct segment_tree {
seg node[N << 2]; 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);
} // add the point x with y
void modify(int l, int r, int pos, int x, ll y) {
if (l == r) {
node[pos].w += y;
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);
} // query the segment [x, y]
ll 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;
ll 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;
} // remove the point that the sum of [0, it] is x, return its id
int remove(int l, int r, int pos, ll 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;
}
} sgm; int n, a[N], b[N], t, sum, mmin; int main() {
while (~scanf("%d", &n)) {
sgm.build(1, n, ROOT);
sum = 0;
repf (i, 1, n)
scanf("%d", &a[i]);
for (int i = n; i >= 1; i--) {
b[i] = sgm.query(1, n, ROOT, 1, a[i] + 1);
sum += b[i];
sgm.modify(1, n, ROOT, a[i] + 1, 1);
}
mmin = sum;
repf (i, 1, n) {
sum = sum - a[i] + (n - 1 - a[i]);
mmin = min(mmin, sum);
}
cout << mmin << endl;
}
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 (树状数组求逆序对)
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 ...
- hdu 13394 Minimum Inversion Number 线段树
题意: 首先给你一个长度为n的序列v,你需要首先找出来逆序对(i<j && v[i]>v[j]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...
随机推荐
- js数组sort方法详解
在处理数组的时候,我们有时候需要对数组进行排序,排序的方法有很多种,但是最好最快的就是利用sort方法进行快速的排序. 我们来看一个例子: var arr1 = [6, 3, 4, 1, 2, 5, ...
- sql创建外键
建立外键关系:先建主表再见从表:主表:create table zhu(code int parimary key,name varchar(20)) ;从表:create table cong(co ...
- Autoencoders and Sparsity(二)
In this problem set, you will implement the sparse autoencoder algorithm, and show how it discovers ...
- 2019.05.08 《Linux驱动开发入门与实战》
第六章:字符设备 申请设备号---注册设备 1.字符设备的框架: 2.结构体,struct cdev: 3.字符设备的组成: 4.例子: 5.申请和释放设备号: 设备号和设备节点是什么关系.? 设备驱 ...
- BZOJ4652: [Noi2016]循环之美(莫比乌斯反演,杜教筛)
Description 牛牛是一个热爱算法设计的高中生.在他设计的算法中,常常会使用带小数的数进行计算.牛牛认为,如果在 k 进制下,一个数的小数部分是纯循环的,那么它就是美的.现在,牛牛想知道:对 ...
- 将字符串使用md5加密
>>> import md5 >>> md5.md5('123').hexdigest() '202cb962ac59075b964b07152d234b70' & ...
- Go语言核心之美 1.5-作用域
变量的作用域是指程序代码中能够有效使用这个变量的范围. 不要将作用域和生命期混在一起. 作用域是代码中的一块区域,是一个编译期的属性:生命期是程序执行期间变量存活的时间段.在此时间段内,变量能够被程序 ...
- Sql延时
IF EXISTS(SELECT * FROM sys.procedures WHERE name='usp_wait30s')BEGIN DROP PROC usp_wait30sENDgocrea ...
- ConcurrentHashMap实现原理--转载
原文地址:http://ajax-xu.iteye.com/blog/1104649 ConcurrentHashMap是Java 5中支持高并发.高吞吐量的线程安全HashMap实现.在这之前我对C ...
- C# 截取中英文混合字符串分行显示宽度相同
/// <summary> /// 截取方法名显示宽度 /// </summary> /// <param name=" ...