P1908 逆序對

纯粹的發表於2024-04-13

原題連結

題解

本質:求一個數前面有幾個數大於它,我們把序列分成幾段,然後對每段分別進行排序,然後找出這個數在前面已經排好序中的序列裡有幾個大於它

code

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

#define ll long long

ll a[500005], b[500005], c[500005]; // a-original, b-replace, c-new
ll ans = 0;

inline void read(ll &x) {
    x = 0;
    ll flag = 1;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

void bg(ll l, ll r)
{

    if (l == r) return;
    ll mid = (l + r) / 2;

    bg(l, mid);
    bg(mid + 1, r);
    ll p1 = l, p2 = mid + 1, p3 = l;
    while (p1 <= mid && p2 <= r)
    {
        if (c[p1] <= c[p2]) b[p3++] = c[p1++];//為什麼要等於?因為等於不算逆序對
        else
        {
            b[p3++] = c[p2++];
            ans += mid - p1 + 1;
        }
    }
    while (p1 <= mid) b[p3++] = c[p1++];
    while (p2 <= r) b[p3++] = c[p2++];

    for (ll i = l; i <= r; i++) c[i] = b[i];
    return;
}

int main()
{
    ll n;
    read(n);

    for (ll i = 1; i <= n; i++)
    {
        read(a[i]);
        c[i]=a[i];
    }

    bg(1, n);
    write(ans);
    return 0;
}

相關文章