A - Ultra-QuickSort
本题要求逆序对,可以用归并排序或树状数组去求。
题解:离散化+树状数组。
将每个数值压入树状数组中,然后将离散化好的数组,倒叙进行树状数组的更新和查询,ans加上当前压入树状数组的比他小的数据的个数。
ACcode:
/*
* @Author: NEFU_马家沟老三
* @LastEditTime: 2020-06-22 15:48:33
* @优快云 blog: https://blog.youkuaiyun.com/acm_durante
* @E-mail: 1055323152@qq.com
* @ProbTitle:
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#include <iomanip>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define lowbit(x) ((x) & -(x))
const double PI = acos(-1.0);
int tree[500010], n, num[500010];
ll ans;
struct node
{
int val, pos;
} a[500010];
void update(int x)
{
while (x <= n)
{
tree[x]++;
x += lowbit(x);
}
}
ll query(int x)
{
ll res = 0;
while (x > 0)
{
res += (ll)tree[x];
x -= lowbit(x);
}
return res;
}
bool cmp(node x, node y)
{
if (x.val != y.val)
return x.val < y.val;
}
int main()
{
while (~scanf("%d", &n) && n)
{
memset(tree, 0, sizeof(tree));
ans = 0;
rep(i, 1, n)
{
scanf("%d", &a[i].val);
a[i].pos = i;
}
sort(a + 1, a + 1 + n, cmp);
for (int i = 1; i <= n; i++) //离散化
{
num[a[i].pos] = i;
}
per(i, 1, n)
{
update(num[i]);
ans += query(num[i] - 1);
}
printf("%lld\n", ans);
}
return 0;
}