POJ 2299 Ultra-QuickSort

来源:互联网 发布:php将图片转为base64 编辑:程序博客网 时间:2024/06/05 08:59

树状数组求逆序

i= 1  2  3  4  5 

       v= 9  1  0  5  4

     id=  1  2  3  4  5


排序后   i=  1  2  3  4  5

      v= 9  5  4  1  0

    id=  1  4  5  2  3

 f[id]=  1  2  3  4  5

   f[i]=  1  4  5  2  3

(此时就相当于完成了离散化)

然后每次在f[i]所在位置插入1

0 0 0 0 0 ans=0 

1 0 0 0 0 ans=0

1 0 0 1 0 ans=1

1 0 0 1 1 ans=3

1 1 0 1 1  ans=4

1 1 1 1 1 ans=6

每一次插入求出该位置前有多少个一(就相当于每插入一个值查出比该值大的数有多少个)

#include <iostream>#include <cstdio>#include <algorithm>#include <string.h>using namespace std;const int N=500005;struct node{int v,id;}a[N];int f[N],c[N];int n;bool cmp(node x,node y){return x.v>y.v;}int lowbit(int x){    return x&(-x);}void update(int t,int value){    int i;    for(i=t;i<=n;i+=lowbit(i))    {        c[i]+=value;    }}int getsum(int x){    int i;    int temp=0;    for(i=x;i>=1;i-=lowbit(i))    {        temp+=c[i];    }    return temp;}int main(){while(~scanf("%d",&n)&&n){for(int i=1;i<=n;i++){scanf("%d",&a[i].v);a[i].id=i;}sort(a+1,a+n+1,cmp);for(int i=1;i<=n;i++)f[a[i].id]=i;memset(c,0,sizeof(c));long long ans=0;for(int i=1;i<=n;i++)        {            update(f[i],1);            ans+=getsum(f[i])-1;        }        printf("%lld\n",ans);}return 0;}



0 0