poj 2299(离散化+树状数组求逆序数)

题意:求出序列的逆序数之和。

思路:今天做了一道树状数组处理的逆序数,给的数值太大,要离散化处理。结果会超int。




#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int N=500010;
int cnt[N],n;
struct node
{
	int w;
	int id;
}p[N];
int cmp(void const *a,void const *b)
{
	node *c,*d;
	c=(node *)a;
	d=(node *)b;
	return c->w-d->w;
}
int amp(void const *a,void const *b)
{
	node *c,*d;
	c=(node *)a;
	d=(node *)b;
	return c->id-d->id;
}
void plus(int i)  
{  
    while(i<=n)  
    {  
        cnt[i]++;  
        i+=(i&(-i));//值比i大的树状数组都要+1  
    }  
}  
int findsum(int i)  
{  
    int sum=0;  
    while(i>0)  
    {  
        sum+=cnt[i];  
        i-=(i&(-i));  
    }  
    return sum;  
}  
int main()
{
	int i,k,temp;
	while(scanf("%d",&n),n)
	{
		memset(cnt,0,sizeof(cnt));
		for(i=1;i<=n;i++)
		{
			scanf("%d",&p[i].w);
			p[i].id=i;
		}
		k=0;temp=-1;
		qsort(p+1,n,sizeof(p[1]),cmp);
		for(i=1;i<=n;i++)
		{
			if(p[i].w==temp)
				p[i].w=k;
			else
			{
				temp=p[i].w;
				p[i].w=++k;
			}
		}
		__int64 sum=0;
		qsort(p+1,n,sizeof(p[1]),amp);
		for(i=1;i<=n;i++)
		{
			sum+=(i-1-findsum(p[i].w));
			plus(p[i].w);
		}
		printf("%I64d\n",sum);
	}
	return 0;
}


你可能感兴趣的:(编程,算法,百度,ACM,树状数组)