P1774 最接近神的人_NOI导刊2010提高(02)
临考A水题系列。。。
这道题很水,就是让你求逆序对。
树状数组做的跑得慢我不学,我学归并排序的。
逆序对在\(a[i] > a[j]\)的时候有两种贡献的算法:
-
ans += j - t;
-
ans += mid - i + 1
我偏向于第一种,为什么呢?因为紫书里面写的就是第一种。
代码:
#include<cstdio>
const int maxn = 5e5 + 5;
#define ll long long
ll a[maxn], n;
ll t[maxn];
ll ans;
ll read()
{
ll ans = 0, s = 1;
char ch = getchar();
while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
return s * ans;
}
void msort(int l, int r)
{
if(l < r)
{
int mid = (l + r) >> 1;
msort(l, mid);
msort(mid + 1, r);
}
int mid = (l + r) >> 1;
int i = l, j = mid + 1, p = l;
while(i <= mid && j <= r)
{
if(a[i] > a[j])
{
ans += j - p;
t[p++] = a[j++];
}
else t[p++] = a[i++];
}
while(i <= mid) t[p++] = a[i++];
while(j <= r) t[p++] = a[j++];
for(int i = l; i <= r; i++) a[i] = t[i];
}
int main()
{
n = read();
for(int i = 1; i <= n; i++) a[i] = read();
msort(1, n);
printf("%lld\n", ans);
return 0;
}