P1908 逆序对

发布时间 2023-07-27 09:42:51作者: zhuxiaopi

输入格式

第一行,一个数 n,表示序列中有 n个数。

第二行 n 个数,表示给定的序列。序列中每个数字不超过 109109。

输出格式

输出序列中逆序对的数目。

 

依次输入n个数,输入的过程中将树状数组第a[i]加上1,统计比a[i]大的数字的个数的和,依次相加,便是逆序对的个数

#include <iostream>
#include <algorithm>

using namespace std;

#define int long long

int n, m, tree[500010], ans, b[500010];
struct A
{
    int w, i;
} a[500010];

bool cmp(A a, A b)
{
//注意当两个数大小相等时,以它们的下标排序
    return a.w == b.w ? a.i < b.i : a.w < b.w;
}

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

void add(int pos, int x)
{
    while (pos <= n)
    {
        tree[pos] += x;
        pos += lowbit(pos);
    }
}

int query(int pos)
{
    int ans(0);
    while (pos > 0)
    {
        ans += tree[pos];
        pos -= lowbit(pos);
    }
    return ans;
}

signed main()
{
    cin >> n;
    for (int i(1); i <= n; ++i)
    {
        cin >> a[i].w;
        a[i].i = i;
    }
//将a排序,并离散化
    sort(a + 1, a + 1 + n, cmp);
    for (int i(1); i <= n; ++i)
    {
        b[a[i].i] = i;
    }
//统计答案
for (int i(1); i <= n; ++i) { add(b[i], 1); ans += query(n) - query(b[i]); } cout << ans; system("pause"); return 0; }