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(最小逆序数 线段树)的更多相关文章

  1. HDU 1394.Minimum Inversion Number-最小逆序数-完全版线段树(单点增减、区间求和)

    HDU1394.Minimum Inversion Number 这个题求最小逆序数,先建一个空的树,然后每输入一个值,就先查询一下,查询之后,更新线段树,然后遍历一遍,每次将第一个数放到最后之后,减 ...

  2. hdu1394 Minimum Inversion Number(最小逆序数)

    Minimum Inversion Number Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/O ...

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

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

  4. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

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

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

  6. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

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

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

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

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

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

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

随机推荐

  1. 使用 WinAppDeployCmd 部署Win10 App 到移动设备

    WinAppDeployCmd是目前微软提供的Win10 App 部署工具,它和以前的Windows Phone Application Deployment 部署工具有所不同的是,WinAppDep ...

  2. dyld: Library not loaded...

    Libraries and frameworks are designated as Required by default, but you can change this designation ...

  3. linux 服务的操作

    启动和停止服务service 命令用于启动及停止某个服务,例如:service camsd stop    停止 camsd 服务service oracled start   启动 oracled ...

  4. Python 文件操作函数

    这个博客是 Building powerful image classification models using very little data 的前期准备,用于把图片数据按照教程指示放到规定的文 ...

  5. [转]恢复 git reset -hard 的误操作

    转帖:http://hi.baidu.com/configuration/item/97fddeea252818d0eb34c964 有时候使用Git工作得小心翼翼,特别是涉及到一些高级操作,例如 r ...

  6. 新冲刺Sprint3(第七天)

    一.Sprint介绍 商家功能模块持续更新着...... 二.Sprint周期 看板: 燃尽图:

  7. 微信朋友圈转疯了(golang写小爬虫抓取朋友圈文章)

    很多人在朋友圈里转发一些文章,标题都是什么转疯啦之类,虽然大多都也是广告啦,我觉得还蛮无聊的,但是的确是有一些文章是非常值得收藏的,比如老婆经常就会收藏一些养生和美容的文章在微信里看. 今天就突发奇想 ...

  8. 用shebang编写一个ssh自动登陆脚本

    单例模式是软件开发中非常普遍的一种模式.它的主要作用是确保系统中,始终只存在一个类的实例对象. 这样做的好处有两点: 1.对于需要频繁使用的对象,在每次使用时,如果都需要重新创建,并且这些对象的内容都 ...

  9. sql 查询执行的详细时间profile

    1.查看profile的设置 SHOW VARIABLES LIKE '%profil%' 结果如下:profiling OFF 为关闭状态 2.开启profile 结果: 3.执行需要执行的sql ...

  10. ExtJs 学习之开篇(二) Observable 给类添加监听

    html:代码 DOCTYPE html><html><head><meta charset="UTF-8"><title>I ...