HDU-1394 Minimum Inversion Number(线段树求逆序数)
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15675 Accepted Submission(s): 9569
Problem Description
The inversion number of a given number sequence a1, a2, …, an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.
For a given sequence of numbers a1, a2, …, an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, …, an-1, an (where m = 0 - the initial seqence)
a2, a3, …, an, a1 (where m = 1)
a3, a4, …, an, a1, a2 (where m = 2)
…
an, a1, a2, …, an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
这道题目有两个地方可以留意一下。
首先求一个数列的逆序数
首先将这个数列排序,然后从最后一个数,边询问边更新
第二,根据题意,将第一个数放到最后一个,形成的新数列应该怎么求逆序数。其实可以递推,和没有变化前的数列比较逆序数增加了(n-1-a[i])-a[i]
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
using namespace std;
#define MAX 5000
int segTree[MAX*4+5];
int n;
int a[MAX];
int b[MAX];
int c[MAX];
void PushUp(int node)
{
segTree[node]=segTree[node<<1]+segTree[node<<1|1];
}
void build(int node,int begin,int end)
{
if(begin==end)
{
segTree[node]=0;
return;
}
int m=(begin+end)>>1;
build(node<<1,begin,m);
build(node<<1|1,m+1,end);
PushUp(node);
}
void Update(int node,int begin,int end,int ind,int num)
{
if(begin==end)
{
segTree[node]+=num;
return;
}
int m=(begin+end)>>1;
if(ind<=m)
Update(node<<1,begin,m,ind,num);
else
Update(node<<1|1,m+1,end,ind,num);
PushUp(node);
}
int Query(int node,int begin,int end,int left,int right)
{
if(left<=begin&&end<=right)
return segTree[node];
int ret;
int m=(begin+end)>>1;
ret=0;
if(left<=m)
ret+=Query(node<<1,begin,m,left,right);
if(right>m)
ret+=Query(node<<1|1,m+1,end,left,right);
return ret;
}
int cmp(int x,int y)
{
return x<y;
}
int main()
{
int sum;
while(scanf("%d",&n)!=EOF)
{
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
c[i]=a[i];
b[a[i]]=i;
}
build(1,1,n);
sort(a+1,a+n+1,cmp);
for(int i=n;i>=1;i--)
{
sum+=Query(1,1,n,1,b[a[i]]);
Update(1,1,n,b[a[i]],1);
}
int num;
num=sum;
int ans;
ans=sum;
for(int i=1;i<n;i++)
{
num+=-c[i]+(n-1-c[i]);
if(ans>num)
ans=num;
}
printf("%d\n",ans);
}
return 0;
HDU-1394 Minimum Inversion Number(线段树求逆序数)的更多相关文章
- [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 (线段树 单点更新 区间求和 逆序对)
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 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
- HDU 1394 Minimum Inversion Number 线段树
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...
- HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...
- HDU_1394_Minimum Inversion Number_线段树求逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu 13394 Minimum Inversion Number 线段树
题意: 首先给你一个长度为n的序列v,你需要首先找出来逆序对(i<j && v[i]>v[j]) 然后把这个序列的最后一个元素放在第一个位置上,其他元素都向后移动一位. 一 ...
- hdu 1394 Minimum Inversion Number (树状数组求逆序对)
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...
- HDU 1394 Minimum Inversion Number (树状数组)
题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...
- HDU 1394 Minimum Inversion Number(树状数组/归并排序实现
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- 标准代码页(codepage)列表
https://blog.csdn.net/jianggujin/article/details/80325461 这篇文章有待完善 代码页 简称 全称 37 IBM037 IBM EBCDIC (U ...
- 使用jquery操作session
摘要: 今天分享的是使用jquery来处理session.我们将使用sessionStorage对象,它类似与localStorage对象,只是sessionStorage是用来储存session数据 ...
- python 字符串格式化,使用f前缀
格式化一般用%,但后来推荐用format format有进步,可以用索引或者名字,但仍然没有很方便和快捷 # logger.debug('{} {} {} {} {} {}'.format(metho ...
- Dubbo -- 系统学习 笔记 -- 示例 -- 只订阅
Dubbo -- 系统学习 笔记 -- 目录 示例 想完整的运行起来,请参见:快速启动,这里只列出各种场景的配置方式 只订阅 问题 为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如 ...
- webstrom 2017 安装及配置
下载安装:http://www.jetbrains.com/webstorm/ 激活:安装完成后,在打开的 License Activation 窗口中选择 License server. 在输入框输 ...
- mysql字段集合中如何去除其中一个元素
在一对多方案中,我们用逗号拼接进行存储,避免存储多条,或者分表,那么此时出现了存储上如果需要修改的话 就带来了难度,比如规则记录表如下 如果2号规则被删除,那么这张表的所有有2的记录也要被清除掉,此时 ...
- backbone学习笔记:模型(Model)(2)属性验证
Backbone的属性验证有2种方法: 1.Backbone自带简单的验证方法,但是验证规则需要自己实现 通过validate()方法进行验证,验证规则写在此方法里. var RoomModel = ...
- 123、 android Retrofit 介绍和使用(转载)
简单使用:http://blog.csdn.net/bitian123/article/details/51899716 http://blog.csdn.net/duanyy1990/article ...
- Qt下libusb-win32的使用(二)批量读写操作
一.概述 学习libusb-win32的使用.使用批量传输方式与USB开发板进行数据读.写操作.上位机使用Qt做界面, 使用USB开发板的端点2作为批量传输端点. 二.实现 代码比较简单,直接给出,如 ...
- Church 整数前驱的推导
Church 整数前驱的推导比其后继复杂得多,wiki中一个前驱的定义据王垠的博客里说,是他一个数学系的同学花一星期时间推导出来的, 其定义确实比其它介绍lambda的文章中用pair来实现(据说是图 ...