这题用树状数组比归并排序快很多啊~~~
一个是500多一个2000多。
这题用树状数组,主要有两点
I.离散化,把n个数映射到1-n里面,不然内存不够,
II.求一个数组的某一个数据的前面所有数据中比它小(或大)的所有数的个数
对于第一个,我们可以用一个struct,然后里面存两个信息,一个是val,一个是no,其中val是输入的数,no是用来离散化的。
对于第二个,很多人说是树状数组的基本功了,但是我觉得看怎么结束树状数组的。在这里你可以对每一个数update(a[i],1),然后再getsum(a[i])(a[i]是离散化后的数组)。这样的话,你再用i - getsum(a[i])就是逆序数的对数了,如果不好理解的话,可以用5 2 1 4 3这个数组来模拟下。
对于这两个问题解决了之后,这题就简单了
下面给出代码(还是建议自己先想,不过离散化没接触的,可能会比较难想,树状数组还行吧)

CODE
1
/**//*
2
ID:Klion
3
PROG:POJ_2299
4
LANG:C++
5
树状数组版
6
比归并排序快多了~~~
7
注意两点,I.离散化
8
II.树状数组求一个离散化后的数组里面的某一个数的前面的数据中
9
有多少个比它小的数
10
*/
11
#include<iostream>
12
using namespace std;
13
const int MAX = 500006;
14
int tree[MAX];
15
typedef struct
16

{
17
int val,no;//val是输入的值,no表示是第几个,用来离散化用
18
}Node;
19
Node num[MAX];//存输入数据
20
int aa[MAX];//存离散化之后的信息,离散化啊离散化
21
int cmp(const void * a,const void * b)//离散化时用用到的排序模板
22

{
23
return ((Node *)a)->val - ((Node *)b) ->val;
24
}
25
void update(int idx,int val)
26

{//树状数组的更新
27
while(idx <= MAX)
28
{
29
tree[idx] += val;
30
idx += (idx & -idx);
31
}
32
return ;
33
}
34
int getsum(int idx)
35

{//树状数组的求和
36
int ret = 0;
37
while(idx > 0)
38
{
39
ret += tree[idx];
40
idx -= (idx & -idx);
41
}
42
return ret;
43
}
44
int main(void)
45

{
46
int n;
47
__int64 sum;
48
while((EOF != scanf("%d",&n)) && n)
49
{
50
for(int i = 1;i <= n;i++)
51
{
52
scanf("%d",&num[i].val);
53
num[i].no = i;
54
}
55
//用于离散化的排序
56
qsort(num+1,n,sizeof(num[0]),cmp);
57
for(int i = 1;i <= n;i++)
58
{//这里离散化,把n个点映射到1-n
59
aa[num[i].no] = i;
60
}
61
memset(tree,0,sizeof(tree));
62
sum = 0;
63
for(int i = 1;i <= n;i++)
64
{//更新及计算结果
65
update(aa[i],1);
66
sum += (i - getsum(aa[i]));
67
}
68
printf("%I64d\n",sum);
69
}
70
}
71