仍旧在练习线段树中。。这道题一开始没有完全理解搞了一上午,感到了自己的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 线段树+逆序对相关推荐

  1. Minimum Inversion Number 线段树

    The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that s ...

  2. HDU 1394 Minimum Inversion Number(线段树的单点更新)

    点我看题目 题意 :给你一个数列,a1,a2,a3,a4.......an,然后可以求出逆序数,再把a1放到an后,可以得到一个新的逆序数,再把a2放到a1后边,,,,,,,依次下去,输出最小的那个逆 ...

  3. HDU - 1394 Minimum Inversion Number(树状数组)

    题目链接:点击查看 题目大意:线段树求逆序数,给出的数列可以组成环,问怎么样求可以让逆序数最小,输出最小值 题目分析:看到这个题的第一反应是暴力枚举5000种情况,因为感觉这个题的N给的不是很大,但是 ...

  4. hdu1394 Minimum Inversion Number 线段树和树状数组

    题意: 输入一个长度 n 第二行给出长度为n的数组,数组的值刚好为0到n-1这n个数. 然后每次把数组的第一个数放到最后一个,放n-1次,共有n个排列,这n个排列就有n个逆序数,输出这n个逆序数的最小 ...

  5. 逆序数2 HDOJ 1394 Minimum Inversion Number

    题目传送门 1 /* 2 求逆序数的四种方法 3 */ 1 /* 2 1. O(n^2) 暴力+递推 法:如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]. ...

  6. 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 ...

  7. Minimum Inversion Number HDU - 1394(求一个数字环的逆序对+多种解法)

    题意: 给出n个数(0~n-1,每个数仅出现一次),问它长为n的循环序列中逆序对最少的数量. 多种解法:暴力+树状数组+分治+规律推导公式 题目: The inversion number of a ...

  8. HDU - 5592 ZYBs Premutation(线段树,逆序对)

    题目链接:点击查看 题目大意:给出 n 个数,分别表示数列 p 前缀 [ 1 , i ] 的逆序对个数,现在要求还原数列 p 题目分析:设 a[ i ] 为前缀 [ 1 , i ] 的逆序对个数,则 ...

  9. HUOJ 1394 Minimum Inversion Number

    本题两种解法,暴搜,线段树,线段树只是处理最初序列,找出最初的逆序数,之后每次移动为当前逆序数+比移动数大的数-比移动数小的数. 做本题时完全没有想法,完全没有~copy胡浩大神代码,第一次抄错题.. ...

  10. HDOJ1394 Minimum Inversion Number【线段树】

    需要注意的就是给出的数是0~n-1,而线段树根节点范围是1-n 所以main中insert要num[i]+1. 当然,根节点范围换成0~n-1就不需要了. Problem : 1394 ( Minim ...

最新文章

  1. matlab inviter,水中石
  2. 340亿美元买下红帽!IBM百年以来最大手笔,云市场翻身之战!
  3. 用 Hadoop 进行分布式并行编程, 第 2 部分 程序实例与分析
  4. C#窗体应用设置多窗体和设置启动窗体
  5. no Bloomberg, wind, ceic, csmar at cambridge
  6. CentOS6挂载读写NTFS分区(ntfs-3g)
  7. 请讲一下浏览器从接收到一个URL,到最后展示出页面,经历了哪些过程
  8. python完全支持面向对象编程_Python面向对象编程
  9. [TJOI2011] 书架(线段数优化dp + 单调栈)
  10. Android pm 命令详解
  11. java webview 对象_Android – 将JSON对象从webview javascript传递给java
  12. 4段简短代码教你用Python读写Excel
  13. PAT乙级 1005继续3n+1猜想
  14. Unreal Engine 4 基于网格的水面模拟实现
  15. 3级城市选择(数据库版)
  16. andr实现微信小程序抓包
  17. Mac终端如何切换成管理员
  18. 安装net_speeder
  19. android studio 倒计时,Android studio 学习3:实现倒计时、画板
  20. JAVA多线程-(三)如何让线程暂停

热门文章

  1. 菜鸟学EJB(二)——在同一个SessionBean中使用@Remote和@Local
  2. HBase源码分析:HTable put过程
  3. Xml读取和写入以及新建
  4. DrawText()
  5. 从java project到dynamic web project
  6. Lesson 002 —— 网络七层模型
  7. VS2010-MFC(菜单:VS2010菜单资源详解)
  8. poj 2778 DNA Sequence
  9. halcon图像处理的基本思路
  10. Spring Boot源码分析