码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1394 Minimum Inversion Number 线段树

时间:2017-08-04 17:12:36      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:ring   code   代码   one   display   思路   while   ide   problem   

  题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1394

  题目大意:给出一个n排列, 进行n中变换, 求最大逆序数

  解题思路: 已知一个数列的逆序数, 那么他的变换可以O(1)求出来, 所以现在的主要问题就是求一组排列的逆序数, n 小于等于5000, 完全可以暴力, 但是现在用线段树做。由于是一组n排列, 而且我们只关心一个数前面的比他大的数, 那当我们插入a[i]时, 只需要查询0 ~ i-1 中 a[i] ~ n-1 内的数的个数就可以了, 我们可以先造一颗0的空树, 这样我们查询的时候就就直接查全部序列就可以。(吃饭去了)

  代码: 

技术分享
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>

#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

const int maxn = 5000+7;
using namespace std;
int sum[4*maxn];
int arr[maxn];

void Pushplus( int rt ) {
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    return;
}

void build( int l, int r, int rt ) {
    sum[rt] = 0;
    if( l == r ) return;
    int m = (l + r) >> 1;
    build( lson );
    build( rson );
    return;
}

int Query( int L, int R, int l, int r, int rt ) {
    if( L <= l && r <= R ) {
        return sum[rt];
    }
    int m = (l + r) >> 1;
    int ret = 0;
    if( L <= m ) ret += Query( L, R, lson );
    if( R > m ) ret += Query( L, R, rson );
    return ret;
}

void update(int p, int l, int r, int rt) {
    if( l == r ) {
        sum[rt]++;
        return;
    }
    int m = (l+r) >> 1;
    if( p <= m ) update(p, lson);
    else update(p, rson);
    Pushplus(rt);
}

int main() {
    int n;
    while( scanf( "%d", &n ) == 1 ) {
        build( 0, n-1, 1 );
        int sum = 0;
        for( int i = 0; i < n; i++ ) {
            scanf( "%d", arr + i );
            sum += Query( arr[i], n-1, 0, n-1, 1 );
            update(arr[i], 0, n-1, 1);
        }
        int ret = sum;
        for( int i = 0; i < n; i++ ) {
            sum += n - arr[i] - arr[i] - 1;
            ret = min( ret, sum );
        }
        printf( "%d\n", ret );
    }
}
View Code

  思考: 

HDU 1394 Minimum Inversion Number 线段树

标签:ring   code   代码   one   display   思路   while   ide   problem   

原文地址:http://www.cnblogs.com/FriskyPuppy/p/7286071.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!