HDU 4217 树状数组+二分查找

比赛中做出这题来让我开心了好久啊~哈哈~温习了一下树状数组。

开始惊奇和雄爷爷和我说树状数组没有这个性质,我不信。后来码畜来之后,才发现,确实树状数组确实没有这么个性质。

于是开始用vector做= =TLE.... 还好想出了二分这个好办法... 1234ms AC了... 嘿嘿...

其实我还是挺膜拜那些4500++的code...

#include<iostream>
#include<string>
using namespace std;

int N,K;
int c[399999];
int lowbit( int x ){
 	return x&(-x);
}
void modify( int num,int v )
{
 	 while( num<=N ){
	  		c[num]+=v;
	  		num+=lowbit(num);
	 }
}
int getnum( int n )
{
 	int x=n;
 	int rec=0;
 	while(x){
	 	   rec+=c[x];
	 	   x-=lowbit(x);
  	}
  	return rec;
}

int del( int n )
{
 	int l=1,r=N;
 	int mid;
 	while( (mid=(r+l)/2)&&l<r )
 	{
	 	   if( getnum(mid)>=n )
	 	   	   r=mid;
	 	   else
	 	   	   l=mid+1;
  	}
  	modify(mid,-1);
	return mid;
}

int main()
{
 	int T;
 	scanf( "%d",&T );
 	int ca=1;
 	while( T-- )
 	{
	 	   __int64 ans=0;
	 	   memset( c,0,sizeof(c) );
	 	   scanf( "%d %d",&N,&K );
	 	   for( int i=1;i<=N;i++ ){
		   		modify( i,1 );
		   }
		   for( int i=1;i<=K;i++ )
		   {
		   		int num;
		   		scanf( "%d",&num );
		   		ans+=del(num);
   		   }
   		   printf( "Case %d: %I64d\n",ca++,ans );
  	}
 	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值