HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number
【题目链接】Minimum Inversion Number
【题目类型】最小逆序数 线段树
&题意:
求一个数列经过n次变换得到的数列其中的最小逆序数
&题解:
先说一下逆序数的概念:
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那末它们就称为一个逆序。
一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列。
如2431中,21,43,41,31是逆序,逆序数是4,为偶排列。
换一种说法:
逆序对:数列a[1],a[2],a[3]…中的任意两个数a[i],a[j] (i<j),如果a[i]>a[j],那么我们就说这两个数构成了一个逆序对
逆序数:一个数列中逆序对的总数
如数列 3 5 4 8 2 6 9
(5,4)是一个逆序对,同样还有(3,2),(5,2),(4,2)等等
如何求解?
用树状数组或线段树
还是以刚才的序列
3 5 4 8 2 6 9
大体思路为:新建一个数组,将数组中每个元素置0
0 0 0 0 0 0 0
取数列中最大的元素,将该元素所在位置置1
0 0 0 0 0 0 1
统计该位置前放置元素的个数,为0
接着放第二大元素8,将第四个位置置1
0 0 0 1 0 0 1
统计该位置前放置元素的个数,为0
继续放第三大元素6,将第六个位置置1
0 0 0 1 0 1 1
统计该位置前放置元素的个数,为1
…
…
这样直到把最小元素放完,累加每次放元素是该元素前边已放元素的个数,这样就算出总的逆序数来了
在统计和计算每次放某个元素时,该元素前边已放元素的个数时如果一个一个地数,那么一趟复杂度为O(n),总共操作n趟,复杂度为O(n^2),和第一种方法的复杂度一样了,那我们为什么还用这么复杂的方法
当然,在每次统计的过程中用树状数组可以把每一趟计数个数的复杂度降为O(logn),这样整个复杂度就变为O(nlogn)
最后再根据已知的逆序数弄出公式 就可以\(O(n)\)的复杂度取最小值就好了
【时间复杂度】\(O(nlogn)\)
&代码:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define lsn b,m,rt<<1
#define rsn m+1,e,rt<<1|1
const int maxn=200000+9;
int seg[maxn<<2];
int a[maxn],x[maxn];
int n;
void PushUp(int rt)
{
seg[rt]=seg[rt<<1]+seg[rt<<1|1];
}
void Update(int id,int xx,int b,int e,int rt)
{
if (b==e){
seg[rt]+=xx;
return ;
}
int m=b+e>>1;
if (id<=m)
Update(id,xx,lsn);
else
Update(id,xx,rsn);
PushUp(rt);
}
int Query(int l,int r,int b,int e,int rt)
{
if (l<=b&&e<=r){
return seg[rt];
}
int m=b+e>>1;
int ans=0;
if (l<=m)
ans+=Query(l,r,lsn);
if (m<r)
ans+=Query(l,r,rsn);
return ans;
}
int main()
{
while(~scanf("%d",&n)){
memset(seg,0,sizeof(seg));
memset(x,0,sizeof(x));
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=n-1;i>=0;i--){
x[i]=Query(0,a[i],0,n-1,1);
Update(a[i],1,0,n-1,1);
}
int sum=0;
for(int i=0;i<n;i++){
// printf("%d\n",x[i]);
sum+=x[i];
}
int re=sum;
// printf("sum=%d\n",sum);
for(int i=0;i<n;i++){
sum=sum+n-1-2*a[i];
re=min(re,sum);
// printf("sum=%d\n",sum);
}
printf("%d\n",re);
}
return 0;
}
HDU 1394 Minimum Inversion Number(最小逆序数 线段树)的更多相关文章
- HDU 1394.Minimum Inversion Number-最小逆序数-完全版线段树(单点增减、区间求和)
HDU1394.Minimum Inversion Number 这个题求最小逆序数,先建一个空的树,然后每输入一个值,就先查询一下,查询之后,更新线段树,然后遍历一遍,每次将第一个数放到最后之后,减 ...
- hdu1394 Minimum Inversion Number(最小逆序数)
Minimum Inversion Number Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/O ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- 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 Minimum Inversion Number ...
- HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)
题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS Memory Limit: 32768 K Description The inve ...
- 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(线段树/树状数组求逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu 1394 Minimum Inversion Number(逆序数对) : 树状数组 O(nlogn)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 //hdu 题目 Problem Description The inversion number ...
随机推荐
- tableView的高度问题
新建tableView 到一个普通的视图控制器的View 下,如果大小是全屏高 ,你的数据最下面显示不全,需要在设置高度时候,用屏幕高度-65 即可
- 回文数组(Rotate Array (JS))
旋转一个数组. function rotate(array,n){ var l =array.length,a=array.map(function(x){return x}),arr=[]; n=n ...
- jenkins之安装篇
自动化学习过程中老师介绍了一个工具jenkins,感觉很不错,学习ingjenkins的war包下载地址http://mirrors.jenkins-ci.org/war/Hudson的war包下载地 ...
- oracle实现split函数功能
转载: http://blog.csdn.net/jojo52013145/article/details/6758279在实际的应用中,为了让PL/SQL 函数返回数据的多个行,必须通过返回一个 R ...
- IOS一些高效的第三方框架库
MBProgressHUD ——进展指示符库 苹果的应用程序一般都会用一种优雅的,半透明的进度显示效果,不过这个API是不公开的,因此你要是用了,很可能被清除出AppStore.而 MBProgres ...
- AFNetworking 3.0
AFN 一.什么是AFN 全称是AFNetworking,是对NSURLConnection的一层封装 虽然运行效率没有ASI高,但是使用比ASI简单 在iOS开发中,使用比较广泛 AFN的githu ...
- python 模拟用户登录代码
需求:输入用户名,判断用户是否被锁定,锁定则退出,否则进入密码验证,输入三次错误密码之后此用户被锁定. userlist.txt里,用":"将用户名.密码.状态码分开: [root ...
- DFS序详解
dfs序就是一棵树在dfs遍历时组成的节点序列. 它有这样一个特点:一棵子树的dfs序是一个区间. 下面是dfs序的基本代码: void dfs(int x,int pre,int d){//L,R表 ...
- 如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:
32位的Windows:---------------------------------------------------------------------------1. 运行->cmd ...
- VBA编程常用语句
.Option Explicit '强制对模块内所有变量进行声明 Option Private Module '标记模块为私有,仅对同一工程中其它模块有用,在宏对话框中不显示 Option Compa ...