题目链接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. POI解析Excel代码

    // 批量区域数据导入 @Action(value = "area_batchImport") public String batchImport() throws IOExcep ...

  2. day 7-13 数据库的数据类型

    一. 数据类型 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 注意:int类型的宽度是显示宽度,并非是数据的存储宽度 详细的介绍:http:// ...

  3. C# Note5:使用相对路径读取文件

    一.C#中使用相对路径读取配置文件 一般Solution的目录结构如下图所示: (如过看不到某些文件,可以点击 “显示所有文件” 图标) 方法一:由于生成的exe文件在bin\debug目录下,可以使 ...

  4. 爬取B站视频

    先安装you_get pip install you_get 爬取代码,爬了个ASMR的,学习困了自我催眠 import sys from you_get import common as you_g ...

  5. Socket构造但不连接

    Socket socket = new Socket(); SocketAddress address = new InetSocketAddress("localhost",80 ...

  6. JQ获取URL中是否含有某个字符的话,对页面进行某种操作

    一.//JQ获取URL中是否含有某个字符的话,对页面进行某种操作 例:如果URL中含有xia的字符,就在页面引入一个cssvar str=window.location.href; //获取地址栏UR ...

  7. SpringBoot之加载自定义配置文件

    SpringBoot默认加载配置文件名为:application.properties和application.yml,如果需要使用自定义的配置文件,则通过@PropertySource注解指定. J ...

  8. 9.Pod控制器概念和基本操作2

    利用一个简单的例子来启动一个deployment的Pod控制器 [root@master song]# cat deploy.yml apiVersion: apps/v1 kind: Deploym ...

  9. QXcbConnection: Could not connect to display

    import matplotlib; matplotlib.use('agg') 注意:要添加到所有matplotlib前面,否则不起作用

  10. 排列组合n选m算法

    找10组合算法,非递归 http://blog.csdn.net/sdhongjun/article/details/51475302