日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2018.07.08 hdu1394 Minimum Inversion Number(线段树)

發布時間:2024/8/22 编程问答 31 如意码农
生活随笔 收集整理的這篇文章主要介紹了 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(线段树)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。