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): 9514 Accepted Submission(s): 5860
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.
10
1 3 6 9 0 8 5 7 4 2
16
题目大意:
求逆序数。也就是给你一个序列,每次求逆序数,然再把第一个数放到这个序列的末尾,构成新的序列。问你这n个序列的最小的逆序数。
解题思路:
1、对于每一个序列。其原来的逆序数记为 pre , 假设当前把该序列 第一个数 a[0] 移动到尾部,那么新序列的逆序数为 pre-a[i]+(n-a[i]-1)
由于序列中比a[i]大的数有 n-a[i]-1 个。比a[i]小的有 a[i]个。
因此仅仅需求出第一个序列的逆序数,依次能够递推出这n个序列的逆序数,求出最小的就可以
2、求第一个序列的逆序数的方法
(1)暴力算法,据说不会超时
(2)线段树,建 [0,n]这段树。对于数据 a[i] ,先查询 (a[i]+1,n) 这段的值也就是比a[i]大的数的个数也就是 逆序数,然后插入 (a[i],a[i]) 值为1
代码:
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std; const int maxn=5100; struct tree{
int l,r,sum;
}a[maxn*4]; int data[maxn],n,m; void build(int l,int r,int k){
a[k].l=l;
a[k].r=r;
a[k].sum=0;
if(l<r){
int mid=(l+r)/2;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
}
} void insert(int l,int r,int k,int c){
if(l<=a[k].l && a[k].r<=r){
a[k].sum+=c;
}else{
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) insert(l,r,2*k,c);
else if(l>=mid+1) insert(l,r,2*k+1,c);
else{
insert(l,mid,2*k,c);
insert(mid+1,r,2*k+1,c);
}
a[k].sum=a[2*k].sum+a[2*k+1].sum;
}
} int query(int l,int r,int k){
if(l<=a[k].l && a[k].r<=r){
return a[k].sum;
}else{
int mid=(a[k].l+a[k].r)/2;
if(r<=mid) return query(l,r,2*k);
else if(l>=mid+1) return query(l,r,2*k+1);
else{
return query(l,mid,2*k) + query(mid+1,r,2*k+1) ;
}
}
} void solve(){
int ans=0;
build(1,n,1);
for(int i=1;i<=n;i++){
ans+=query(data[i]+1,n,1);
insert(data[i]+1,data[i]+1,1,1);
//cout<<data[i]<<" "<<ans<<endl;
}
int tmp=ans;
for(int i=1;i<=n;i++){
tmp-=data[i];
tmp+=n-data[i]-1;
if(tmp<ans) ans=tmp;
}
cout<<ans<<endl;
} int main(){
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++) scanf("%d",&data[i]);
solve();
}
return 0;
}
HDU 1394 Minimum Inversion Number (数据结构-段树)的更多相关文章
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址: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——————【线段树单点增减、区间求和】
Minimum Inversion Number Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- 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 T ...
- HDU - 1394 Minimum Inversion Number (线段树求逆序数)
Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs ( ...
- HDU 1394 Minimum Inversion Number(线段树的单点更新)
点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...
- HDU 1394 Minimum Inversion Number (线段树 单点更新 求逆序数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给你一个n个数的序列,当中组成的数仅仅有0-n,我们能够进行这么一种操作:把第一个数移到最 ...
- HDU 1394 Minimum Inversion Number(线段树求逆序对)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1394 解题报告:给出一个序列,求出这个序列的逆序数,然后依次将第一个数移动到最后一位,求在这个过程中 ...
- hdu 1394 Minimum Inversion Number 【线段树求逆序数】
之前写过树状数组的,再用线段树写一下--- #include<cstdio> #include<cstring> #include<iostream> #inclu ...
随机推荐
- Ajax 下拉列表联动显示
一般处理程序文件 代码 using System;using System.Web;using System.Linq;using System.Data.Linq;using System.Text ...
- poj1639 Picnic Planning 最小度数限制生成树
题意:若干个人开车要去park聚会,可是park能停的车是有限的,为k.所以这些人要通过先开车到其它人家中,停车,然后拼车去聚会.另外,车的容量是无限的,他们家停车位也是无限的. 求开车总行程最短. ...
- POJ 2991 Crane(线段树+计算几何)
POJ 2991 Crane 题目链接 题意:给定一个垂直的挖掘机臂.有n段,如今每次操作能够旋转一个位置,把[s, s + 1]专程a度,每次旋转后要输出第n个位置的坐标 思路:线段树.把每一段当成 ...
- 验证码 Captcha 之大插件
验证码 Captcha 之大插件小用 不知何年何月才能完成OADemo啊,总之还是一步一步来吧,这段时间开始着手了,先做登陆. 前段时间研究了一下在CentOS7下安装Mysql和Memcached ...
- Qt 4.7.4 完美动态编译发布动态调试,以及静态编译发布
首先是准备工作,去QT主页下载独立的QT类库安装包以及完整QT SDK安装包,还有QT Creator for windows 版 下载地址:http://qt.nokia.com/downloads ...
- 14.3.5.3 How to Minimize and Handle Deadlocks 如何减少和处理死锁
14.3.5.3 How to Minimize and Handle Deadlocks 如何减少和处理死锁 这个章节建立关于死锁的概念信息,它解释如何组织数据库操作来减少死锁和随后的错误处理: D ...
- nohup sort -k1 -n -t$'\t' ./bigfile.16 -o./test/bigfile.16.ok &
nohup sort -k1 -n -t$'\t' ./bigfile.16 -o./test/bigfile.16.ok &
- 安装Oracle JDK 7.0与8.0 for Mac OS X后Eclipse启动报错的解决之道
启动 Eclipse 时,直接报错The JVM shared library "/Library/Java/JavaVirtualMachines/jdk1.8.0_25.jdk/Cont ...
- GB2312引进和使用的字体
一个:先上图看到的结果,下面的屏幕截图android在测试的结果"SD卡测试".."GPS测试"和其他字符24x24字体进来. 二: 1)简单介绍 ...
- Selenium 验证picklist是可被正确选中且是有序的(动态数组赋值)
原代码: <select id="edit-submitted-im-interesting-in" class="form-select required&quo ...