2018.07.08 hdu1394 Minimum Inversion Number(线段树)
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
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
Author
CHEN, Gaoli
Source
ZOJ Monthly, January 2003
Recommend
Ignatius.L | We have carefully selected several similar problems for you: 1166 1698 1540 1542 1255
看到題的第一眼還以為是動態逆序對,讀完題后發現竟然是一道水題。
這道題想讓我們求的是在不斷改變元素的順序之后所有逆序對的最小值。怎么做?首先我們知道在進行n" role="presentation" style="position: relative;">nn次輪換之后數列又變回去了,所以我們只需用一種高效的方法統計出每次輪換后數列逆序對的個數就行了。
怎么統計?
顯然第一次逆序對直接上樹狀數組(線段樹)求so" role="presentation" style="position: relative;">soso easy" role="presentation" style="position: relative;">easyeasy,那么之后的輪換呢?用n" role="presentation" style="position: relative;">nn次樹狀數組==gg" role="presentation" style="position: relative;">gggg,因此可以想到這樣輪換有特殊的性質。沒錯就是這樣。我們考慮當前隊首的元素,這個元素從隊首移到隊尾的操作可以拆成隊首彈出,隊尾插入的操作,設上一次的逆序對數為sum" role="presentation" style="position: relative;">sumsum,那么這個元素從隊首彈出顯然會使sum" role="presentation" style="position: relative;">sumsum減少a1−1" role="presentation" style="position: relative;">a1?1a1?1,道理顯然(a1" role="presentation" style="position: relative;">a1a1之后有a1−1" role="presentation" style="position: relative;">a1?1a1?1個數比它小),同理,這個元素從隊尾插入會使sum" role="presentation" style="position: relative;">sumsum變大n−a1" role="presentation" style="position: relative;">n?a1n?a1(證明同理)。這樣看來的話似乎一個循環比比大小就沒了啊。
代碼如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 5005
using namespace std;
int n,bit[N],a[N],sum,ans;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
return ans;
}
inline int lowbit(int x){return x&-x;}
inline void update(int x,int v){for(int i=x;i<=n;i+=lowbit(i))bit[i]+=v;}
inline int query(int x){int ans=0;for(int i=x;i;i-=lowbit(i))ans+=bit[i];return ans;}
int main(){
while(~scanf("%d",&n)){
sum=ans=0;
memset(a,0,sizeof(a));
memset(bit,0,sizeof(bit));
for(int i=1;i<=n;++i){
a[i]=read()+1;
sum+=query(n)-query(a[i]);
update(a[i],1);
}
ans=sum;
for(int i=1;i<=n;++i)ans=min(ans,sum=sum-a[i]+1+n-a[i]);
printf("%d\n",ans);
}
return 0;
}
總結
以上是生活随笔為你收集整理的2018.07.08 hdu1394 Minimum Inversion Number(线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cannot resolve symbo
- 下一篇: webpack配置指南