HDU 1394 (逆序数) Minimum Inversion Number
原来求逆序数还可以用线段树,涨姿势了。
首先求出原始序列的逆序数,然后递推每一个序列的逆序数。
#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的更多相关文章
- HDU 1394 & ZOJ 1484 Minimum Inversion Number
(更新点查询区间) 这题重在想到,写代码很容易了..这题是利用线段树求逆序数,不按给定的顺序建树,而是有序地插入.比如每插入一个数,就统计之前插入的那些数里比他大的有多少个,这个数就是此时的逆序数,然 ...
- 线段树 逆序对 Minimum Inversion Number HDU - 1394 Laptop
Minimum Inversion Number HDU - 1394 求最小反转数,就是求最少的逆序对. 逆序对怎么求,就是先把所有的数都初始化为0,然后按照顺序放入数字,放入数字前查询从这个数往后 ...
- HDU 1394 逆序数 线段树单点跟新 | 暴力
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu 1394 逆序数(线段树)
http://acm.hust.edu.cn/vjudge/problem/15764 http://blog.csdn.net/libin56842/article/details/8531117 ...
- 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 逆序数/树状数组
Minimum Inversion Number Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showprob ...
- hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 //hdu 题目 Problem Description The inversion number ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number ...
随机推荐
- 利用 random 与 tertools 模块解决概率问题
Python 中的 random 与 tertools 模块可以得到伪随机数与排列.组合,下面利用这两个模块求解一些有趣的概率问题. 一.random 与 tertools 模块 random 模块常 ...
- 浅谈 OneAPM 在 express 项目中的实践
[编者按]OneAPM 运营团队,近日在 github 上发现了一篇文章,特别奉献给大家.本文作者王宇先生从2015年年初就开始使用我们的产品,也是OneAPM 的忠实用户. OneAPM 是一个优秀 ...
- POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)
题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...
- solr的collection,shard,replica,core概念
一.collection 1.由多个cores组成一个逻辑索引叫做一个collection.一个collection本质上是一个可以跨越多个核的索引,同时包含冗余索引. 2.collection由不同 ...
- ExtJs之Ext.form.field.ComboBox组合框
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- BZOJ 1452: [JSOI2009]Count 二维树状数组
1452: [JSOI2009]Count Description Input Output Sample Input Sample Output 1 2 HINT Source 题解:设定C[101 ...
- C#打开得到路径
FolderBrowserDialog path = new FolderBrowserDialog(); path.ShowDialog(); MessageBox.Show(path.Select ...
- 540A: Combination Lock
题目链接:http://codeforces.com/problemset/problem/540/A 题意: 输入的两个长度一样的数,求对应位置的某位数到下一个数需要最小的步长,每次只能先前或先后走 ...
- mq_notify
NAME mq_notify - 通知进程可以接收一条消息 (REALTIME) SYNOPSIS #include <mqueue.h> int mq_notify(mqd_t mqde ...
- Android核心分析之十五Android输入系统之输入路径详解
Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...