树状数组
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; }