树状数组
int low(int i){
return i&(-i);
}
更新
void update(int i){
while(i<=n){
num[i]++;
i+=low(i);
}
}
求和
int sum(int i){
int s=0;
while(i>0){
s+=num[i];
i-=low(i);
}
return s;
}
离散化的方式:
struct Node
{
int val;
int pos;
};
Node node[500005];
int reflect[500005];
val存放原数组的元素,pos存放原始位置,即node[i].pos = i。
把这些结构体按照val的大小排序。
reflect数组存放离散化后的值,即reflect[node[i].pos] = i。
这样从头到尾读入reflect数组中的元素,即可以保持原来的大小关系,又可以节省大部分空间。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 500010
typedef struct In{
int val;
int pos;
};
In node[N];
int num[N],c[N],n;
int cmp(const void *a,const void *b){
In *c=(In *)a;
In *d=(In *)b;
return c->val-d->val;
}
int low(int i){
return i&(-i);
}
void insert(int i){
while(i<=n){
num[i]++;
i+=low(i);
}
}
int search(int i){
int s=0;
while(i>0){
s+=num[i];
i-=low(i);
}
return s;
}
int main(){
int i,j,v,t;
long long s;
while(scanf("%d",&n),n){
memset(num,0,sizeof(num));
memset(node,0,sizeof(node));
memset(c,0,sizeof(c));
for(i=1;i<=n;i++){
scanf("%d",&node[i].val);
node[i].pos=i;
}
qsort(node+1,n,sizeof(node[0]),cmp);//排序
for(i=1;i<=n;i++){
c[node[i].pos]=i;//离散化
}
for(s=0,i=1;i<=n;i++){
v=c[i];
insert(v);
t=search(v-1);
s+=i-t-1;
}
printf("%lld\n",s);
}
return 0;
}