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]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...
随机推荐
- Spring Cloud Netflix Eureka client源码分析
1.client端 EurekaClient提供三个功能: EurekaClient API contracts are:* - provide the ability to get Instance ...
- javaweb二
除了servlet规范,还有filter,listener.filter和servlet相似,但是在servlet之前执行,主要区别是有一个FilterChain接口可以执行拦截方法. import ...
- javafx Hanoi
Netbean java8 source code :http://files.cnblogs.com/files/rojas/HNT.zip screenshot: 1 model /* ...
- array01.js
//1.获取指定范围内的随机数 function getRadomNum(min,max){ return Math.floor(Math.random() * (max - min + 1)) + ...
- c# for 和 foreach
1给定长度 不需要计算长度的 for比foreach循环效率高 2 在不确定长度 或者计算长度有性能损耗的时候 用foreach比较方便 2336 循环语句是编程的基本语句,在C#中除了沿用C语言的循 ...
- HDU 1716 排列2
排列2 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- LuoguP2763 试题库问题(最大流)
建图同_____ 代码: #include<queue> #include<cstdio> #include<cstring> #include<algori ...
- CMDB学习之四 ——DEBUG模式
定义一个debug,进行解析调试,到测试文件 配置文件,配置debug模式,定义环境变量, #!/usr/bin/env python # -*- coding:utf-8 -*- import os ...
- python学习日记-180823
列表 a=[ ] 1.负数下标:a=[-1]指的是列表a最后一个下标,-2指倒数第二个下标 2.切片——利用切片获得子列表 a[1:4]——'1'切片开始处的下标,‘4’切片结束处的下标(不包括此下标 ...
- Elasticsearch5.0.1 + Kibana5.0.1 + IK 5.0.1
Elasticsearch5.0.1 + Kibana5.0.1 + IK 5.0.1安装记录 最近工作需要,开始研究ES,当前ES的最新版本为5.0.1,从之前的2.x的版本号一下升级到5.x,主要 ...