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

题目大意:逆序数:即假设在数组a中,假如i<j,但是a[i]>a[j]。

现在有一个数组,含有n个数(为0-(n-1)的一个排列),依次把第一个数,放到数组最后面,求其中逆序数数目最小是多少?

例:

Sample Input
10 1 3 6 9 0 8 5 7 4 2
 
Sample Output
16

解题思路:首先,我们要思考对于一个数组怎样求出它的逆序数的总个数,这里有两种方法,最简单的是,直接暴力,两层循环就可以搞定。这里主要讲一下第二种方法,用线段树也可以很巧妙的求它的逆序数个数,我们先建立一颗空树,然后一个一个将节点插入树中,我们把数组中数的大小看成在树中的位置,然后每插入一个节点,就统计大于这个数的数目,即产生的逆序数的数目,然后再更新该位置的数值为1.这样就求出了初始状态下的逆序数sum了。

然后要求出最小的逆序数,因为数组是0到n-1的一个排列,所以如果当你把第一个数从第一个放到最后一个的时候,逆序数就会减少a【i】个,同时增加n-(a[i]+1)个。所以我们只需要枚举依次把第一个数放到最后位置,所产生的逆序数sum+(n-2*num[i]-1)取最小值即可。

附上代码

暴力解法

#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
int n,a[]; int main()
{
while(~scanf("%d",&n))
{
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
int sum=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(a[i]>a[j])
sum++;
}
}
int ans=inf;
for(int i=;i<=n;i++)
{
sum+=(n-*a[i]-);
ans=min(ans,sum);
}
printf("%d\n",ans);
}
return ;
}

线段树解法

#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
#define maxn 10005
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define pushup() tree[root]=tree[root<<1]+tree[root<<1|1]
int n,tree[maxn<<],num[maxn<<]; /*
void pushdown(int l,int r,int root)
{
if(add[root])
{
add[root<<1]+=add[root];
add[root<<1|1]+=add[root];
tree[root<<1]+=l*add[root];
tree[root<<1|1]+=r*add[root];
add[root]=0;
}
}
void build(int l,int r,int root)
{
add[root]=0;
if(l==r)
{
tree[root]=num[tot++];
return;
}
int mid=l+r>>1;
build(lson);
build(rson);
pushup();
}*/
void update(int pos,int val,int l,int r,int root)
{
if(l==r)
{
tree[root]=val;
return;
}
int mid=l+r>>;
if(pos<=mid)
update(pos,val,lson);
else
update(pos,val,rson);
pushup();
}
int query(int L,int R,int l,int r,int root)
{
if(L<=l&&R>=r)
return tree[root];
int ans=,mid=l+r>>;
if(L<=mid)
ans+=query(L,R,lson);
if(R>mid)
ans+=query(L,R,rson);
return ans;
} int main()
{
while(~scanf("%d",&n))
{
memset(tree,,sizeof(tree));//初始时,为空树,直接memset
int sum=;
for(int i=;i<=n;i++)
{
scanf("%d",&num[i]);
sum+=query(num[i]+,n,,n,);
update(num[i]+,,,n,);
}
int ans=sum;
for(int i=;i<=n;i++)
{
sum+=(n-*num[i]-);
ans=min(ans,sum);
}
printf("%d\n",ans);
}
return ;
}

hdu1394逆序数(线段树)的更多相关文章

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

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

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

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

  3. 51Nod 1019 逆序数(线段树)

    题目链接:逆序数 模板题. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a) ...

  4. POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化

    我用的线段树写的. num数组表示已插入的数值的个数. 由于a[i]数值很大,但是n不是很大,所以要离散化处理 9 1 0 5 4 离散化后 4 1 0 3 2 这样保证最大值不会超过n #inclu ...

  5. hdu1394 分治 or 线段树

    利用分治求一次逆序数,然后每次把第一个元素放到末尾,设该交换元素的值为x,设上一次求得的逆序数为y,那么此时的逆序数等于y - x + (n - x - 1),减去x是因为x作为第一个元素,其后共有x ...

  6. 逆序对 线段树&树状数组 (重制版)

    逆序对的定义:长度为n的数组a,求满足i<j时a[i]>a[j]条件的数对个数. 第一次接触这种问题的人可能是更先想到的是n^2去暴力数前面有几个比他大的数. int main() { i ...

  7. 51nod1019逆序数(归并排序/树状数组)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...

  8. 2019.01.22 bzoj3333: 排队计划(逆序对+线段树)

    传送门 题意简述:给出一个序列,支持把ppp~nnn中所有小于等于apa_pap​的'扯出来排序之后再放回去,要求动态维护全局逆序对. 思路:我们令fif_ifi​表示第iii个位置之后比它大的数的个 ...

  9. CF #301 E:Infinite Inversions(逆序数,树状数组)

    A-Combination Lock  B-School Marks   C-Ice Cave   D-Bad Luck Island   E-Infinite Inversions E:Infini ...

随机推荐

  1. React Native之通知栏消息提示(android)

    React Native之通知栏消息提示(android) 一,需求分析与概述 1.1,推送作为手机应用的基本功能,是手机应用的重要部分,如果自己实现一套推送系统费时费力,所以大部分的应用都会选择使用 ...

  2. PHP中对象是按值传递还是按引用传递?

    1.首先,什么是按值传递和按引用传递? 按值传递就是仅仅把值传递过去,相当于传递的是值的拷贝,而按引用传递传递的是内存的地址. 在 PHP5 中,如果按引用传递,就是将 zval 的地址赋给另一个变量 ...

  3. SQLSERVER sa 用户密码修改的方法

    本次驱动人生病毒的收获 . 偷懒总会有报应. . 应用(数据库或者是web应用nginx等.)都不要使用最高级别权限用户来使用 虽然这样的环境问题最少. . 密码还是需要定期更换的,虽然有成本,但是也 ...

  4. mac下php开发环境的搭建

    1.phpstorm 在官网:https://www.jetbrains.com/phpstorm/,下载最新版:phpstorm-2016.2.1 在http://15.idea.lanyus.co ...

  5. Hbase存储思想

  6. 在eclipse中spring的xml配置文件标签中class路径全限定名自动提示设置

    这个自动提示其实很简单,没有网上说的那些要在help下的Install中输入网址来下载更新一堆东西那么复杂. 只需要打开Help — — >Eclipse Marketplace... 然后在该 ...

  7. uwsgi加nginx部署django restframework前后端分离项目

    一.uwsgi和nginx简介 1.uwsgi(摘抄于百度百科): uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与 ...

  8. linux audit审计(8)--ausearch搜索audit日志文件

    ausearch这个工具,可以针对指定的事件来搜索audit日志文件.默认情况下,ausearch搜索/var/log/audit/audit.log这个文件. The ausearch utilit ...

  9. DAY01、计算机组成及操作系统

    一.编程与编程的目的: 1.什么是语言?什么是编程语言? 语言是一事物与另一事物之间沟通的介质 编程语言就是程序员与计算机之间沟通的介质 2.什么是编程? 程序员把自己想要让计算机做的事用编程语言表达 ...

  10. linux 地址解析协议 arp

    随便转载,保留出处:http://www.cnblogs.com/aaron-agu/ arp –na #查看 arp –s 123.253.68.209 00:19:56:6F:87:D4 #添加