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(线段树求最小逆序数对)的更多相关文章

  1. [HDU] 1394 Minimum Inversion Number [线段树求逆序数]

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  2. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  3. hdu - 1394 Minimum Inversion Number(线段树水题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...

  4. HDU 1394 Minimum Inversion Number 线段树

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...

  5. HDU 1394 Minimum Inversion Number(线段树 或 树状数组)

    题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...

  6. hdu 1394 Minimum Inversion Number (树状数组求逆序对)

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  7. HDU 1394 Minimum Inversion Number (树状数组)

    题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...

  8. HDU 1394 Minimum Inversion Number(树状数组/归并排序实现

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  9. hdu 13394 Minimum Inversion Number 线段树

    题意: 首先给你一个长度为n的序列v,你需要首先找出来逆序对(i<j && v[i]>v[j]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...

随机推荐

  1. Mahout的推荐系统

    Mahout的推荐系统 什么是推荐系统 为什使用推荐系统 推荐系统中的算法 什么是推荐系统 为什么使用推荐系统? 促进厂商商品销售,帮助用户找到想要的商品 推荐系统无处不在,体现在生活的各个方面 图书 ...

  2. 记录一个mybatis编写xml遇到的错误:java.lang.unsupportedOperationException

    写完xml里的sql在执行xml中的sql时报错,经过排查找到问题出在方法中的resultType这个属性的类型上 如图所示:只需要将sortedSet改为set集合里所存储的对象的类型即可. 这里我 ...

  3. nodejs学习(三)--express连接mysql数据库,mysql查询封装

    一.说一下 连接不同的数据库需要安装相应的插件,此demo使用mysql数据库,需自行安装mysql数据库软件. 新建数据库webapp, 新建表users: 二.直接开码 npm install m ...

  4. 三分钟上手Highcharts简易甘特图

    根据业务需求,找到了这个很少使用的图形,话不多说,看看该如何使用.首先要引入支持文件:可根据链接下载. exporting.js:https://img.hcharts.cn/highcharts/m ...

  5. 【hihocoder 1378】网络流二·最大流最小割定理

    [Link]:http://hihocoder.com/problemset/problem/1378 [Description] [Solution] 在求完最小割(最大流)之后; 可以在剩余网络中 ...

  6. SpringCloud组件和概念介绍

    一:什么是微服务(Microservice) 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及 ...

  7. golang 数组

    数组是Go语言编程中最常用的数据结构之一.顾名思义,数组就是指一系列同一类型数据的集合.数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数组的长度. 在Go语言中数组 ...

  8. 【LeetCode-面试算法经典-Java实现】【144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)】

    [144-Binary Tree Preorder Traversal(二叉树非递归前序遍历)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a bina ...

  9. thinkphp5空控制器和空操作

    thinkphp5空控制器和空操作 一.总结 1.空控制器和空操作用:空控制器和空操作都是为了防止网站上的用户恶意输入,网站上线的话必须加上, 2.空操作:空操作就是在一般的控制器里面加上一个 _em ...

  10. Android连接socket服务器上传下载多个文件

    android连接socket服务器上传下载多个文件1.socket服务端SocketServer.java public class SocketServer { ;// 端口号,必须与客户端一致 ...