POJ 2299 Ultra-QuickSort(树状数组+离散化)

 

树状数组

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;
}
            


 

 

你可能感兴趣的:(POJ 2299 Ultra-QuickSort(树状数组+离散化))