HDU-1394 Minimum Inversion Number 线段树+逆序对
仍旧在练习线段树中。。这道题一开始没有完全理解搞了一上午,感到了自己的shabi。。
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15527 Accepted Submission(s): 9471
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,和0-n的一个数列,求这个数列的最小逆序对数,最小逆序对表示,给定数列每次都将第一个数放到最后一个位置,如此变化n次至变换回原状,在这n种不同的数列中,逆序对数的最小值即为所求(N<=5000)每组样例多组数据
明白题意后想到求逆序对的三种方法,第一种暴力法,第二种归并,第三种树状数组和线段树,由于在学习线段树于是果断练习用线段树编写
此处线段树的作用是求出原数列的逆序对
对于每次变换,我们发现,第一个数移到最后一位,只需要在上一步里求出的逆序对减去上一步第一位的数,并加上比上一步第一位要大的数即可
下面是代码:
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 5005
int sum[maxn<<2];
int a[maxn];void updata(int now)
{sum[now]=sum[now<<1]+sum[now<<1|1];
}void build(int l,int r,int now)
{sum[now]=0;if(l==r) return;int mid=(l+r)>>1;build(l,mid,now<<1);build(mid+1,r,now<<1|1);
}int query(int L,int R,int l,int r,int now)
{if(L<=l && r<=R)return sum[now];int mid=(l+r)>>1;int total=0;if(L<=mid) total+=query(L,R,l,mid,now<<1);if(R>mid) total+=query(L,R,mid+1,r,now<<1|1);return total;
}void point_change(int loc,int l,int r,int now)
{if(l==r){sum[now]++;return;}int mid=(l+r)>>1;if(loc<=mid) point_change(loc,l,mid,now<<1);else point_change(loc,mid+1,r,now<<1|1);updata(now);
}int main()
{int n;while(~scanf("%d",&n)){build(0,n-1,1);int number=0;for(int i=0;i<n;i++){scanf("%d",&a[i]);number+=query(a[i],n-1,0,n-1,1);point_change(a[i],0,n-1,1);}int ans=number;for(int i=0;i<n;i++){number+=n-a[i]-a[i]-1;ans=min(ans,number);}printf("%d\n",ans);}return 0;
}
转载于:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346259.html
HDU-1394 Minimum Inversion Number 线段树+逆序对相关推荐
- Minimum Inversion Number 线段树
The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...
- HDU 1394 Minimum Inversion Number(线段树的单点更新)
点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...
- HDU - 1394 Minimum Inversion Number(树状数组)
题目链接:点击查看 题目大意:线段树求逆序数,给出的数列可以组成环,问怎么样求可以让逆序数最小,输出最小值 题目分析:看到这个题的第一反应是暴力枚举5000种情况,因为感觉这个题的N给的不是很大,但是 ...
- hdu1394 Minimum Inversion Number 线段树和树状数组
题意: 输入一个长度 n 第二行给出长度为n的数组,数组的值刚好为0到n-1这n个数. 然后每次把数组的第一个数放到最后一个,放n-1次,共有n个排列,这n个排列就有n个逆序数,输出这n个逆序数的最小 ...
- 逆序数2 HDOJ 1394 Minimum Inversion Number
题目传送门 1 /* 2 求逆序数的四种方法 3 */ 1 /* 2 1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]. ...
- Minimum Inversion Number HDU - 1394(权值线段树/树状数组)
The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...
- Minimum Inversion Number HDU - 1394(求一个数字环的逆序对+多种解法)
题意: 给出n个数(0~n-1,每个数仅出现一次),问它长为n的循环序列中逆序对最少的数量. 多种解法:暴力+树状数组+分治+规律推导公式 题目: The inversion number of a ...
- HDU - 5592 ZYBs Premutation(线段树,逆序对)
题目链接:点击查看 题目大意:给出 n 个数,分别表示数列 p 前缀 [ 1 , i ] 的逆序对个数,现在要求还原数列 p 题目分析:设 a[ i ] 为前缀 [ 1 , i ] 的逆序对个数,则 ...
- HUOJ 1394 Minimum Inversion Number
本题两种解法,暴搜,线段树,线段树只是处理最初序列,找出最初的逆序数,之后每次移动为当前逆序数+比移动数大的数-比移动数小的数. 做本题时完全没有想法,完全没有~copy胡浩大神代码,第一次抄错题.. ...
- HDOJ1394 Minimum Inversion Number【线段树】
需要注意的就是给出的数是0~n-1,而线段树根节点范围是1-n 所以main中insert要num[i]+1. 当然,根节点范围换成0~n-1就不需要了. Problem : 1394 ( Minim ...
最新文章
- matlab inviter,水中石
- 340亿美元买下红帽!IBM百年以来最大手笔,云市场翻身之战!
- 用 Hadoop 进行分布式并行编程, 第 2 部分 程序实例与分析
- C#窗体应用设置多窗体和设置启动窗体
- no Bloomberg, wind, ceic, csmar at cambridge
- CentOS6挂载读写NTFS分区(ntfs-3g)
- 请讲一下浏览器从接收到一个URL,到最后展示出页面,经历了哪些过程
- python完全支持面向对象编程_Python面向对象编程
- [TJOI2011] 书架(线段数优化dp + 单调栈)
- Android pm 命令详解
- java webview 对象_Android – 将JSON对象从webview javascript传递给java
- 4段简短代码教你用Python读写Excel
- PAT乙级 1005继续3n+1猜想
- Unreal Engine 4 基于网格的水面模拟实现
- 3级城市选择(数据库版)
- andr实现微信小程序抓包
- Mac终端如何切换成管理员
- 安装net_speeder
- android studio 倒计时,Android studio 学习3:实现倒计时、画板
- JAVA多线程-(三)如何让线程暂停