HDU-1394 Minimum Inversion Number(线段树求逆序数)
2015-12-29 22:43
351 查看
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]
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;
相关文章推荐
- 【VMCloud云平台】私有云门户第一朵SQL云
- 二进制中1的个数
- VS 2010调用Matalab R2010b生成的DLL库的配置问题
- 高效团队建设与团队领导
- 第九周 广义表算法库
- uva10720
- Connect to LocalDB in Visual Studio Server Explorer
- 工作三年的java程序员修行之路
- python - zipfile
- chapter9:文件与文件系统的压缩与打包之(2)完整备份dump
- 挑战无处不在
- 【学神-RHEL7】1-27-break跳出循环shift左移参数和函数的使用
- iOS的certificates和provisioning profiles
- 数值<2>__笔记(8)
- 认证和授权
- python标准库00 学习准备
- SQL语句优化之提高查询效率
- 风向标 ps:表白csdn
- 权限管理
- ARM 知识汇总