POJ-2299

题目:求逆序数

https://vjudge.net/problem/POJ-2299

思路:

才学的树状数组准备写题,谁知道第一题就被暴打。

树状数组求逆序数,没输入一个数在之前输入过的数中找比当前数大的数。

用树状数组实现即,维护一段数组,每次输入一个数用树状数组的特性,找到之前比它小的数的个数。

用已经输入过的数减掉,就是比当前数大的数。

同时此题需要用到离散化的思想,看了多个博客后明白了。

就是把输入N个的大小差距特别大的数转化为从(1-N)来表示,同时不改变原输入的大小顺序,

可以减少开的树状数组的大小。

代码:

//#include <bits/stdc++.h>
#include <iostream>
#include <memory.h>
#include <algorithm>
using namespace std;
const int MAXN = 500000+10;

int a[MAXN];
int c[MAXN];
int n;

struct Node
{
    int v;
    int w;
    bool operator < (const Node & that) const{
        return this->v < that.v;
    }
};
Node node[MAXN];

int lowbit(int x)
{
    return x&-x;
}

void update(int pos,int v)
{
    while (pos <= n)
    {
        c[pos] += v;
        pos += lowbit(pos);
    }
}

int getsum(int pos)
{
    int sum = 0;
    while (pos > 0)
    {
        sum += c[pos];
        pos -= lowbit(pos);
    }
    return sum;
}

int main()
{
    while (cin>>n&&n)
    {

        for (int i = 1;i<=n;i++)
        {
            cin>>node[i].v;
            node[i].w = i;
        }

        sort(node+1,node+n+1);

        //memset(a,0, sizeof(a));
        memset(c,0, sizeof(c));
        for (int i = 1;i<=n;i++)
            a[node[i].w] = i;

        long long ans = 0;
        for (int i = 1;i <= n;i++)
        {
            update(a[i],1);
            ans += i-getsum(a[i]);
        }
        cout<<ans<<endl;

    }

    return 0;
}
/*
5
9 1 0 5 4
*/

  

猜你喜欢

转载自www.cnblogs.com/YDDDD/p/10221850.html