【Hdu】Minimum Inversion Number(逆序,线段树)

利用线段树在nlogn的时间复杂度内求一段数的逆序。

由于给的序列是由0 ~ n -1组成的,求出初始的逆序之后可以递推出移动之后的逆序数。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 5555;
int tree[maxn << 2];
int n;
void BuildTree(int L,int R,int pos){  //建树
    tree[pos] = 0;
    if(L == R)
        return ;
    int m = (L + R) >> 1;
    BuildTree(L,m,pos << 1);
    BuildTree(m + 1,R,(pos << 1)|1);
    return ;
}
void UpDate(int aim,int L,int R,int pos){
    if(L == R){
        tree[pos] ++;
        return ;
    }
    int m = (L + R) >> 1;
    if(aim <= m)
        UpDate(aim,L,m,pos << 1);
    else
        UpDate(aim,m + 1,R,(pos << 1)|1);
    tree[pos] = tree[pos << 1] + tree[(pos << 1)|1];
    return ;
}
int Query(int l,int r,int L,int R,int pos){
    if(l <= L && R <= r)
        return tree[pos];
    int m = (L + R) >> 1;
    int ans = 0;
    if(l <= m)
        ans += Query(l,r,L,m,pos << 1);
    if(m <  r)
        ans += Query(l,r,m + 1,R,(pos << 1)|1);
    return ans;
}
int main(){
    while(scanf("%d",&n) != EOF){
        BuildTree(0,n - 1,1);
        int Sum = 0;
        int x[maxn];
        for(int i = 0 ; i < n ; i++){   //利用nlog(n)时间复杂度求逆序数
            scanf("%d",&x[i]);
            Sum += Query(x[i], n - 1,0,n - 1,1);
            UpDate(x[i],0,n - 1,1);
        }
        int ans = Sum;
        for(int i = 0 ; i < n; i++){
            Sum = Sum + n - 2 * x[i] - 1;
            ans = min(ans,Sum);
        }
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-10 09:38:41

【Hdu】Minimum Inversion Number(逆序,线段树)的相关文章

HDU 1394 &lt;Minimum Inversion Number&gt; &lt;逆序数&gt;&lt;线段树&gt;

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 seq

HDU 1394 Minimum Inversion Number (数据结构-线段树)

Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9514    Accepted Submission(s): 5860 Problem Description The inversion number of a given number sequence a1, a2, ..., an

ACM Minimum Inversion Number 解题报告 -线段树

C - Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u 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.

HDU Minimum Inversion Number

经典的线段树求解逆序数问题. 运用了一个逆序数的性质,如果一个数从首位换到尾位,这其逆序数将减少y[i],增加n-y[i]-1. 举个例子说明,如果一个排列3 1 2 0 4本来三前面应该有三个数比他小的,但是现在3在首位,则说明3产生的逆序数有3个,而将3换到尾位后,就说明比3大的都在3前面了,所以此时3的逆序数有n-y[i]-1(5-3-1 = 1). 线段树的话,先建立一个空树,每次不断的查询插入.就是一开始先查询树中有多少个数比当前要插入的值大,就说明改数拥有多少个逆序数.查询后,在把改

hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1394 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

HDU 2665 Kth number 可持久化线段树

题意:给n个数和m个询问,询问l,r,k是从l~r中的第k小 思路:可持久化线段树的模板题 说下自己对可持久化线段树的理解吧 可持久化线段树的是可以保存历史版本的线段树,就是插进去第i个数的线段树的状态,这样我们可以通过state[r]-state[l-1]来得到state[l~r] 朴素做法就是维护n颗线段树,但是这样一般都会MLE 可持久化线段树利用了每次插入数只修改了线段树上一条链的特性来每次插入一个数只新建一条链来维护历史版本,空间复杂度O(n*logn+n*logn) 原树+新建的链

(中等) POJ 2828 Buy Tickets , 逆序+线段树。

Description: Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue… The Lunar New Year was approaching, but unluckily the Little Cat still had schedules going here and there. Now, he h

HDU - 1394 - Minimum Inversion Number (线段树 - 单点更新,区间求和)

题目传送:Minimum Inversion Number 思路:线段树,求最小逆序数,先可以通过n*logn的时间用线段树求出初始的逆序对数,然后递推求出其他的解,递推过程看代码 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include &

HDU 1394 Minimum Inversion Number(线段树求逆序数啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 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,