原来求逆序数还可以用线段树,涨姿势了。

首先求出原始序列的逆序数,然后递推每一个序列的逆序数。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ; int n, p, qL, qR;
int sum[maxn], a[ + ]; void update(int o, int L, int R)
{
if(L == R) { sum[o]++; return; }
int M = (L + R) / ;
if(p <= M) update(o*, L, M);
else update(o*+, M+, R);
sum[o] = sum[o*] + sum[o*+];
} int query(int o, int L, int R)
{
if(qL <= L && qR >= R) return sum[o];
int ans = ;
int M = (L + R) / ;
if(qL <= M) ans += query(o*, L, M);
if(qR > M) ans += query(o*+, M+, R);
return ans;
} int main()
{
//freopen("in.txt", "r", stdin); while(scanf("%d", &n) == )
{
memset(sum, , sizeof(sum)); for(int i = ; i < n; i++) scanf("%d", &a[i]);
int inv = ;
for(int i = ; i < n; i++)
{
p = a[i];
qL = a[i]; qR = n - ;
inv += query(, , n - );
update(, , n - );
}
int ans = inv;
for(int i = ; i < n; i++)
{
inv = inv + n - a[i]* - ;
ans = min(ans, inv);
}
printf("%d\n", ans);
} return ;
}

线段树

既然要求逆序数了,干脆树状数组,归并排序也都试一试。

由于树状数组lowbit的特点,所以数组下标是从1开始的。但是树状数组要比线段树好写很多。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int n;
int a[maxn], s[maxn]; inline int lowbit(int x) { return x&(-x); } int sum(int x)
{
int ans = ;
while(x > ) { ans += s[x]; x -= lowbit(x); }
return ans;
} void add(int x, int d)
{
while(x <= n) { s[x] += d; x += lowbit(x); }
} int main()
{
//freopen("in.txt", "r", stdin); while(scanf("%d", &n) == )
{
memset(s, , sizeof(s));
for(int i = ; i < n; i++) { scanf("%d", &a[i]); a[i]++; }
int inv = ;
for(int i = ; i < n; i++)
{
inv += sum(n) - sum(a[i]);
add(a[i], );
}
int ans = inv;
for(int i = ; i < n; i++)
{
inv = inv + n + - a[i]*;
ans = min(ans, inv);
}
printf("%d\n", ans);
} return ;
}

树状数组

下面是归并排序,_(:зゝ∠)_

代码不长,但是感觉还是挺容易写错的。

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
int n, inv;
int a[maxn], b[maxn], T[maxn]; void MergeSort(int x, int y)
{
if(y - x > )
{
int m = (x + y) / ;
int p = x, q = m, i = x;
MergeSort(x, m); MergeSort(m, y);
while(p < m || q < y)
{
if(q >= y || (p < m && a[p] <= a[q])) T[i++] = a[p++];
else { T[i++] = a[q++]; inv += m - p; }
}
for(i = x; i < y; i++) a[i] = T[i];
}
} int main()
{
//freopen("in.txt", "r", stdin); while(scanf("%d", &n) == )
{
for(int i = ; i < n; i++) { scanf("%d", &a[i]); b[i] = a[i]; }
inv = ;
MergeSort(, n);
int ans = inv;
for(int i = ; i < n; i++)
{
inv = inv + n - - b[i]*;
ans = min(ans, inv);
}
printf("%d\n", ans);
} return ;
}

归并排序

HDU 1394 (逆序数) Minimum Inversion Number的更多相关文章

  1. HDU 1394 & ZOJ 1484 Minimum Inversion Number

    (更新点查询区间) 这题重在想到,写代码很容易了..这题是利用线段树求逆序数,不按给定的顺序建树,而是有序地插入.比如每插入一个数,就统计之前插入的那些数里比他大的有多少个,这个数就是此时的逆序数,然 ...

  2. 线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop

    Minimum Inversion Number HDU - 1394 求最小反转数,就是求最少的逆序对. 逆序对怎么求,就是先把所有的数都初始化为0,然后按照顺序放入数字,放入数字前查询从这个数往后 ...

  3. HDU 1394 逆序数 线段树单点跟新 | 暴力

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

  4. hdu 1394 逆序数(线段树)

    http://acm.hust.edu.cn/vjudge/problem/15764 http://blog.csdn.net/libin56842/article/details/8531117 ...

  5. HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)

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

  6. hdu 1394 Minimum Inversion Number 逆序数/树状数组

    Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showprob ...

  7. hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394  //hdu 题目   Problem Description The inversion number ...

  8. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  9. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

随机推荐

  1. Sqli-labs less 26a

    Less-26a 这关与26的区别在于,sql语句添加了一个括号,同时在sql语句执行抛出错误后并不在前台页面输出.所有我们排除报错注入,这里依旧是利用union注入. sql语句为SELECT * ...

  2. Mobile Web 调试指南(2):远程调试

    原文:http://blog.jobbole.com/68606/ 原文出处: 阿伦孟的博客(@allenm ) 第一篇中讲解了如何让手机来请求我们开发电脑上的源码,做到了这步后,我们可以改完代码立即 ...

  3. vi/vim使用指北 ---- Moving Around in a Hurry

    上一篇文章中,简单列出了一些基本的Vim操作,也列出了很多的光标移动命令,本章主要是有哪些命令可以更快的移动光标. vim的编辑操作,用得最多就是移动光标,对于很少行的文件来说,基本的命令就够用了,但 ...

  4. DELPHI 获取本月 的第一天 和 最后一天

    USER :DateUtils 使用 StartOfTheMonth 和 EndOfTheMonth 函数获取即可:   procedure TForm1.btn1Click(Sender: TObj ...

  5. 分布式数据存储 - MySQL主从复制高可用方案

    前面几篇文章说道MySQL数据库的高可用方案主从复制.主从复制的延迟产生原因.延迟检测及延迟解决方案(并未从根本上解决),这种主从复制方案保证数据的冗余的同时可以做读写分离来分担系统压力但是并非是高可 ...

  6. codeforces 439D Devu and Partitioning of the Array(有深度的模拟)

    题目 //参考了网上的代码 注意答案可能超过32位 //要达成目标,就是要所有数列a的都比数列b的要小或者等于 //然后,要使最小的要和最大的一样大,就要移动(大-小)步, //要使较小的要和较大的一 ...

  7. Difference Between Initialization and Assignment in C++

    Initialization happens when a variable is given a value at the moment it is created. Assignment obli ...

  8. Windows 7,64位机器上安装DB2 7.2+FP7

    1.要想在Windows 7,64位机器上安装DB2 7.2+FP7,注意:1)拷贝所有安装文件到本地2)设置setup.exe文件兼容windows 20003)使得users用户勾选“完全控制”权 ...

  9. poj 3328(多起点多终点的最短路)

    题目链接:http://poj.org/problem?id=3328 思路:这道题花了我将近3个小时,结果发现是方向搞错了,orz,过了样例之后提交wa,然后换成优先队列就过了.其实题目意思很简单, ...

  10. 【poj3358】消因子+BSGS 或 消因子+欧拉定理 两种方法

    题意:给你一个分数,求它在二进制下的循环节的长度,还有第一个循环节从哪一位开始. For example, x = 1/10 = 0.0001100110011(00110011)w and 0001 ...