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

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

 #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 49

    Less-49 本关与47关基本类似,区别在于没有错误回显,所以我们可以通过延时注入和导入文件进行注入. 利用延时注入 http://127.0.0.1/sqli-labs/Less-49/?sort ...

  2. *args和**kw魔法参数

    学Python挺久了,现在才搞懂这个还是有点惭愧 *args:传入元组,无关键字 **kw:传入字典,有关键字 示例: *args **kw 一起使用时args的参数需在前:

  3. Extjs利用vtype验证表单

    Ext.create('Ext.form.Panel', {         title: '表单验证',         renderTo: Ext.getBody(),         frame ...

  4. LA 3350

    The NASA Space Center, Houston, is less than 200 miles from San Antonio, Texas (the site of the ACM ...

  5. linux使用crontab实现PHP执行定时任务及codeiginter参数传递相关

    http://www.phpddt.com/php/linux-crontab.html crontab: yum install crontabs //安装 说明: /sbin/service cr ...

  6. Freebie: Material Design UI Kit

    点这里 Following the guidelines laid out by Google, this free UI kit has been designed so that you can ...

  7. MYSQL 遭遇 THE TOTAL NUMBER OF LOCKS EXCEEDS THE LOCK TABLE SIZE

    今天进行MySql 一个表数据的清理,经过漫长等待后出现 The total number of locks exceeds the lock table size 提示.以为是table_cache ...

  8. 使用MbrFix.exe修复MBR分区表

    在卸载linux Ubuntu之前,先修复MBR,然后再删除Linux分区就可以了.而MbrFix.exe 就是这样一个Windows 修复MBR的应用程序软件,MbrFix.exe 不仅支持Wind ...

  9. hdu 3389 Game (阶梯博弈)

    #include<stdio.h> int main() { int t,n,ans; int i,j,x; scanf("%d",&t); ;j<=t; ...

  10. python下划线变量的含义

    _xxx      不能用'from module import *'导入 __xxx__ 系统定义名字 __xxx    类中的私有变量名 核心风格:避免用下划线作为变量名的开始. "单下 ...