hdu 1394 Minimum Inversion Number || ZOJ Monthly, January 2003 || 线段树 + 逆序数

hdu 1394 Minimum Inversion Number 请戳

  1. 题意:
    给长度为 n 的数组 A(0 <= A[i] <= n - 1)。
    进行 n - 1 次后移操作,每次将排在第一个的元素移到最后那个元素后面。
    没次数组A都有一个逆序数,求最小的逆序数。

  2. 思路:
    线段树计算逆序数,然后所有逆序数都可以递推出来,取最小的即可。
    去年作死都没想通为什么线段树能够写求出逆序数,今天看了下。。。居然秒懂。(那么问题来了!我去年干啥去了?)

  3. 复杂度:
    时间复杂度:O(n * log(n))
    空间复杂度:O(4 * n)

  4. 代码:

/* ***********************************************
Author        :Ilovezilian
Created Time  :2015/9/4 0:57:03
File Name     :seg_tree_2.cpp
************************************************ */

#include <bits/stdc++.h>
#define INF 0x7fffffff
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N = 0,maxn = 5555, mod = 1e9+7;
int sum[maxn<<2];

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

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

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);
    pushup(rt);
}

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, ret = 0;
    if(L <= m) ret += query(L, R, lson);
    if(R > m) ret += query(L, R, rson);
    return ret;
}

int x[maxn];

void solve()
{
    int n;
    while(~scanf("%d", &n))
    {
        build(0, n - 1, 1);

        int sum = 0;
        for(int i = 0; i < n; i ++)
        {
            scanf("%d", x + i);
            sum += query(x[i], n - 1, 0, n - 1, 1); //逆序数就是每次求和。
            update(x[i], 0, n - 1, 1);//然后更新
        }
        int ret = sum;
        for(int i = 0; i < n; i ++)
        {
            sum += n - x[i] - x[i] - 1; //这个递推有意思
            ret = min(ret, sum);
        }
        printf("%d\n", ret);
    }
}

int main()
{
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    solve();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章