HDU1394 Minimum Inversion Number
来源:互联网 发布:雷神笔记本怎么样知乎 编辑:程序博客网 时间:2024/06/11 16:42
HDU1394 Minimum Inversion Number
标签:线段树,树状数组
http://www.sakurasake.icoc.me/nd.jsp?id=7#_np=2_327
Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Problem Description
The inversion number of a given numbersequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < jand ai > aj.
For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0numbers to the end of the seqence, we will obtain another sequence. There aretotally 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 ofthe above sequences.
Input
The input consists of a number of testcases. Each case consists of two lines: the first line contains a positiveinteger n (n <= 5000); the next line contains a permutation of the nintegers from 0 to n-1.
Output
For each case, output the minimum inversionnumber on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
Author
CHEN, Gaoli
Source
ZOJMonthly, January 2003
分析:快速求逆序数,暴力算法主要分为两步:穷举逆序数,通过公式推出结果
公式为sum=sum-a[i]+(n-a[i]-1)
第二步几乎不可能优化,所以可以使用线段树优化第一步,时间复杂度为O(n log n)
当然通过树状数组应该也可以,就没有写代码了2333
举个栗子
序列3,2,5,4,0,1
3之前没有数大于它本身,val[1]=0
2之前有3大于它,val[2]=1
5之前没有数大于它本身,val[3]=0
4之前有5大于它,val[4]=1
0之前有3,2,5,4,大于它,val[5]=4
1之前有3,2,5,4大于它,val[6]=5
所以实际上,每插入val[i],就查询在[val[i],n-1]之间的数的个数,依次累加即可
#include<iostream>#include<iomanip>#include<cmath>#include<cstring>#include<ctime>#include<cstdio>#include<cstdlib>#include<algorithm>#include<vector>#include<queue>#include<stack>#define LL(x) ((x)<<1)#define RR(x) ((x)<<1|1)inline int read(){ int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}using namespace std;struct Seg_Tree{ int left,right,val; int calmid() { return (left+right)/2; }}tt[15000];int val[5001];void make(int left,int right,int idx){ tt[idx].left=left; tt[idx].right=right; tt[idx].val=0; if(left==right)return; int mid=tt[idx].calmid(); make(left,mid,LL(idx)); make(mid+1,right,RR(idx));}int query(int left,int right,int idx){ if(left==tt[idx].left&&right==tt[idx].right) return tt[idx].val; int mid=tt[idx].calmid(); if(right<=mid)return query(left,right,LL(idx)); else if(mid<left)return query(left,right,RR(idx)); else return query(left,mid,LL(idx))+query(mid+1,right,RR(idx));}void change(int id,int idx){ tt[idx].val++; if(tt[idx].left==tt[idx].right)return; int mid=tt[idx].calmid(); if(id<=mid) change(id,LL(idx)); else change(id,RR(idx));}int main(){ int i,n,sum; while(scanf("%d",&n)==1) { make(0,n-1,1); for(i=0;i<n;i++)sum=0; for(i=0;i<n;i++) { scanf("%d",&val[i]); sum+=query(val[i],n-1,1); change(val[i],1); } int ret=sum; for(i=0;i<n;i++) { sum=sum-val[i]+(n-val[i]-1); ret=min(ret,sum); } printf("%d\n",ret); } return 0;}
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- HDU1394:Minimum Inversion Number
- HDU1394:Minimum Inversion Number
- HDU1394--Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- HDU1394--Minimum Inversion Number
- hdu1394-Minimum Inversion Number
- HDU1394 Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- HDU1394 Minimum Inversion Number
- Instability(typedef pair<LL,int> P;)
- 每日一个linux命令(6):su、su
- 选择控件只显示一行
- 《剑指offer》问题6 从尾到头打印链表 Java实现
- 1047. 编程团体赛(20)
- HDU1394 Minimum Inversion Number
- [UOJ#34]多项式乘法(FFT)
- 基本类型和引用类型作为参数传递
- Qt DLL总结-创建及调用QT的 DLL
- SpringMVC前后台交互
- Cocopods提交自己库及坑
- 高并发量网站解决方案
- Express笔记-two
- HDU 2094 产生冠军