void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

给出一组数据,需要交换相邻的数据使得最后从小到达排列好。。。。。省赛一道题啊啊啊!!!求逆序数呗,当时我用树状数组,可恶的long long啊啊

这道题直接套模版不行,因为数据特别大并且还有负数,所以必须给离散化,把所有数据标号后从小到大排列,然后按照其数组下标把每个数据重新赋值, 从1-N

这样离散的数据就被重新聚合起来了,可以直接套模版了

因为交换次数跟数据值没关,只跟他们大小关系序列有关,因次赋值后大小关系不变。。。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500010
struct node
{
    int val,n;
}co[MAX];
int c[MAX];
__int64 sum;
int cmp1(const void *a,const void *b)
{
    node *aa=(node*)a,*bb=(node*)b;
    return aa->val-bb->val;
}
int cmp2(const void *a,const void *b)
{
    node *aa=(node*)a,*bb=(node*)b;
    return aa->n-bb->n;
}
int lowbit(int x)
{
    return x&(-x);
}
void update(int x)
{
    while(x<MAX)
    {
        c[x]++;
        x+=lowbit(x);
    }
}
int get(int x)
{
    int sum=0;
    while(x>0)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
int main()
{
    int n,x;
    while(scanf("%d",&n)!=EOF,n)
    {
        sum=0;
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++)
        {
            scanf("%d",&co[i].val);
            co[i].n=i;
        }
        qsort(co,n,sizeof(co[0]),cmp1);
        for(int i=0;i<n;i++)
        co[i].val=i+1;
        /*for(int i=0;i<n;i++)//直接离散化
        a[co[i].n]=co[i].val;
        for(int i=n-1;i>=0;i--)
        {
            sum+=get(a[i]);
            update(a[i]);
        }*/
        qsort(co,n,sizeof(co[0]),cmp2);//按照下标再次排序,还原当初的序列
        for(int i=n-1;i>=0;i--)
        {
            sum+=get(co[i].val);
            update(co[i].val);
        }

        printf("%I64d\n",sum);
    }
}
posted on 2011-08-03 00:30  void-man  阅读(319)  评论(0)    收藏  举报