求排列的逆序数

题目链接:https://ac.nowcoder.com/acm/contest/77/A?&headNav=www

这个题可以用树状数组或分冶做

树状数组做法:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

int sum[100010]={0}, n=100010;
int a[100010]={0};

void add(int p, int y)
{
    while(p<=n)
    {
        sum[p]+=y;
        p+=(p&-p);
    }
}

int cx(int p)
{
    int ans=0;
    while(p)
    {
        ans+=sum[p];
        p-=(p&-p);
    }
    return ans;
}

int main()
{
    int n, m;
    LL ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        ans+=i-cx(a[i])-1;
        add(a[i], 1);
    }
    printf("%lld
", ans);

    return 0;
}

分冶做法:

#include <iostream>
using namespace std;
int a[500005], b[1000005];
long long num;
void msort(int s, int t)
{
    int mid = (t + s) / 2;
    int qb = 1, bn = t - s + 1;
    int i, j;
    if (s >= t) return;
    msort(s, mid);
    msort(mid + 1, t);
    for (i = s, j = mid + 1; i <= mid && j <= t; )
    {
        if (a[i] <= a[j])
        {
            b[qb] = a[i];
            i++;
        }
        else
        {
            b[qb] = a[j];
            num += mid - i + 1;
            j++;
        }
        qb++;
    }
    while (j <= t)
    {
        b[qb] = a[j];
        qb++;
        j++;
    }
    while (i <= mid)
    {
        b[qb] = a[i];
        qb++;
        i++;
    }
    for (i = 1, j = s; i < qb; i++, j++)
    {
        a[j] = b[i];
    }
}
int main()
{
    int n, i;
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    num = 0;
    msort(1, n);
    printf("%lld
", num);
    return 0;
}
 
原文地址:https://www.cnblogs.com/shmilky/p/14089038.html