我是靠谱客的博主 害怕故事,最近开发中收集的这篇文章主要介绍HDU1394线段树,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目链接hdu1394
题意:给n个数,可以将前m个数放到最后,一共有n种情况,要求这n种情况中,逆序对个数最少数多少。
思路:在每次插入前,使用线段树求出大于当前点的个数。最后在求出每次移动一个数到最后后逆序对打个数。假如原本序列的逆序对个数为m,第一个数为x,那么如果把0移到最后,那么逆序对数目则为m+n-1-2*x
code:

#include <bits/stdc++.h>
using namespace std;
#define mid ((l + r) >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r

const int maxn = 5500;
int tree[maxn << 2];
int v[maxn];

int query(int rt, int l, int r, int L, int R)
{
    if (l == L && R == r)
        return tree[rt];
    if (R <= mid)
        return query(lson, L, R);
    if (L > mid)
        return query(rson, L, R);
    return query(lson, L, mid) + query(rson, mid + 1, R);
}

void update(int rt, int l, int r, int a)
{
    tree[rt]++;
    if (l == r)
    {
        tree[rt] = 1;
        return;
    }

    if (a <= mid)
        update(lson, a);
    else if (a > mid)
        update(rson, a);
}

int main()
{
    ios::sync_with_stdio(false);
    int n;
    while (cin >> n)
    {
        memset(tree, 0, sizeof(tree));
        int sum = 0;
        int i, num;
        for (i = 0; i < n; i++)
        {
            cin >> v[i];
            sum += query(1, 1, n, v[i] + 1, n);
            update(1, 1, n, v[i] + 1);
        }
        int ans = sum;
        for (i = 0; i < n - 1; i++)
        {
            sum = sum + n - 1 - 2 * v[i];
            ans = min(ans, sum);
        }
        cout << ans << endl;
    }

    return 0;
}

最后

以上就是害怕故事为你收集整理的HDU1394线段树的全部内容,希望文章能够帮你解决HDU1394线段树所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部