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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章