您的位置:首页 > 其它

hdu 2689 sort it(树状数组 逆序数)

2015-12-06 00:03 441 查看
树状数组求逆序数,原来一直没搞明白,今天看了一遍文章讲的很清楚,下面把有关内容粘过来:

对于小数据,可以直接插入树状数组,对于大数据,则需要离散化,所谓离散化,就是将

100 200 300 400 500 ---> 1 2 3 4 5

这里主要利用树状数组解决计数问题。

首先按顺序把序列a[i]每个数插入到树状数组中,插入的内容是1,表示放了一个数到树状数组中。

然后使用sum操作获取当前比a[i]小的数,那么当前i - sum则表示当前比a[i]大的数,如此反复直到所有数都统计完,

比如

4 3 1 2 

i = 1 : 插入 4 : update(4,1),sum(4)返回1,那么当前比4大的为 i - 1 = 0;

i = 2 : 插入 3 : update(3,1),sum(3)返回1,那么当前比3大的为 i - 1 = 1;

i = 3 : 插入 1 : update(1,1),sum(1)返回1,那么当前比1大的为 i - 1 = 2;

i = 4 : 插入 2 : update(2,1),sum(2)返回2,那么当前比2大的为 i - 2 = 2;

过程很明了,所以逆序数为1+2+2=5

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<queue>
#include <deque>
#include <list>
#include <ctime>
#include <stack>
#include <vector>
#include<set>
#define Maxn 1024
#define MOD
typedef long long ll;
#define FOR(i,j,n) for(int i=j;i<=n;i++)
#define DFR(i,j,k) for(int i=j;i>=k;--i)
#define lowbit(a) a&-a
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
using namespace std;
int c[Maxn];
void add(int i,int val)
{ while(i<=Maxn)
{ c[i]+=val;
i+=lowbit(i);
}
}
int sum(int i)
{ int s=0;
while(i>0)
{ s+=c[i];
i-=lowbit(i);
}
return s;
}
int main()
{ int n;
while(~scanf("%d",&n))
{ int num,ans=0;
memset(c,0,sizeof c);
FOR(i,1,n)
{ scanf("%d",&num);
add(num,1);
ans+=i-sum(num);
}
printf("%d\n",ans);

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树状数组