题意:
给出n个数字,求出逆序数。
思路:
树状数组能很容易的求出逆序数,不过前提是以数列本身当作数组C的下标。因为以数
组本身当作下标的时候每一次进行update和sum的时候都能找到前边比x小的数的个
数,这道题由于数组上界太大,无法开那么大的数组所以需要离散化,将原本的数字
排序后放入reflect中,其每一个数字的原来的位置不变,这样就能以位子作为数组下
进行计算。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 500005;
struct Node
{
int val;
int pos;
}node[MAXN];
int n,c[MAXN],reflect[MAXN];
int cmp(Node a,Node b)
{
return a.val < b.val;
}
int lowbit(int x)
{
return x&-x;
}
int update(int x)
{
while(x <= n) {
c[x] += 1;
x += lowbit(x);
}
}
int sum(int x)
{
int sum = 0;
while(x > 0) {
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n) != EOF && n) {
memset(c,0,sizeof(c));
for(int i = 1;i <= n; i++) {
scanf("%d",&node[i].val);
node[i].pos = i;
}
sort(node+1,node+n+1,cmp);
for(int i = 1;i <= n; i++)
reflect[node[i].pos] = i;
long long ans = 0;
for(int i = 1;i <= n; i++) {
update(reflect[i]);
ans += i-sum(reflect[i]);
}
printf("%lld\n",ans);
}
return 0;
}

本文介绍了一种使用树状数组求解逆序数的方法,并通过离散化处理来解决数组上界过大的问题。具体实现包括定义结构体存储数值及其原始位置、比较函数、树状数组的基本操作等。
431

被折叠的 条评论
为什么被折叠?



