hdu 4217 线段树 依次取第几个最小值,求其sum

充分利用下标的资源,tree[]表示节点含有的数据个数

#include <stdio.h>

const int MAXN=262144;

int tree[MAXN<<1];

int pos;

void build(int l,int r,int rt)
{
	tree[rt]=r-l+1;//表示节点含有的数据个数

	if(r==l)
		return ;

	int m=(r+l)/2;

	build(l,m,rt*2);
	build(m+1,r,rt*2+1);
}

void update(int p,int l,int r,int rt)
{
	tree[rt]--;//更新节点的数的个数

	if(r==l)
	{
		pos=l;//此时的pos代表第几个最小值
		return ;
	}

	int m=(r+l)/2;

	if(p<=tree[rt*2])//搜索所需改变的节点
		update(p,l,m,rt*2);
	else
	{
		p-=tree[rt*2];
		update(p,m+1,r,rt*2+1);
	}
}

int main()
{
	int t,k,n,ks,tn=1; 

	__int64 sum;

	scanf("%d",&t);

	while(t--)
	{
		sum=0;

		scanf("%d%d",&n,&k);

		build(1,n,1);

		for(int i=0;i<k;i++)
		{
			scanf("%d",&ks);

			update(ks,1,n,1);

			sum+=pos;
		}

		printf("Case %d: %I64d\n",tn++,sum);
	}

	return 0;
}

  

posted @ 2012-05-08 15:13  shijiwomen  阅读(307)  评论(1编辑  收藏  举报