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 ...
随机推荐
- WebSocket是一种协议
WebSocket,并非HTML 5独有,WebSocket是一种协议.只是在handshake的时候,发送的链接信息头和HTTP相似.HTML 5只是实现了WebSocket的客户端.其实,难点在于 ...
- Redis 学习笔记五 经常使用php函数
PHPRedis的安装在这里: http://blog.csdn.net/xundh/article/details/46288277 键值操作 $redis = new Redis(); $redi ...
- cocos2dx--两个场景切换各函数调用顺序
场景A切换到场景B,有切换特效 调用顺序例如以下:(AAABABABA) A:构造函数 A:onEnter A:onEnterTransitionDidFinish B:构造函数 A:onExitTr ...
- C++智能指针--weak_ptr
weak_ptr是对对象的一种弱引用,它不会添加对象的引用计数.weak_ptr和shared_ptr之间能够相互转换.shared_ptr能够直接赋值给week_ptr,week_ptr可通过调用l ...
- 阿录帮帮忙—spring mvc 的hello world
一:web.xml配置 <!-- Spring MVC配置 --> <servlet> <servlet-name>Spring MVC Dispatcher Se ...
- jquery实现菜单功能(单击展开或者关闭)-一般应用于后台
<!doctype html> <html> <head> <meta charset="gb2312"> <title> ...
- nginx源代码分析--event事件驱动初始化
1.在nginx.c中设置每一个核心模块的index ngx_max_module = 0; for (i = 0; ngx_modules[i]; i++) { ngx_modules[i]-> ...
- codeforces#253 D - Andrey and Problem里的数学知识
这道题是这种,给主人公一堆事件的成功概率,他仅仅想恰好成功一件. 于是,问题来了,他要选择哪些事件去做,才干使他的想法实现的概率最大. 我的第一个想法是枚举,枚举的话我想到用dfs,但是认为太麻烦. ...
- TypeError: Cannot read property 'style' of null 错误解决
错误信息例如以下: JSP代码例如以下: <c:if test ="${not empty excelErrors}"> <div id="excelE ...
- 漫谈并发编程(二):java线程的创建与基本控制
java线程的创建 定义任务 在java中使用任务这个名词来表示一个线程控制流的代码段,用Runnable接口来标记一个任务,该接口的run方法为线程运行的代码段. public ...