原題連結
題解
本質:求一個數前面有幾個數大於它,我們把序列分成幾段,然後對每段分別進行排序,然後找出這個數在前面已經排好序中的序列裡有幾個大於它
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;
}