POJ2892 HDU 1540 Tunnel Warfare, 树状数组

利用树状数组的find_k_th实现找到sum为k的最小位置,  时间复杂度为O(log(n))

/*******************************************************************************
 # Author : Neo Fung
 # Email : [email protected]
 # Last modified: 2012-01-29 22:22
 # Filename: POJ2892 HDU 1540 Tunnel Warfare.cpp
 # Description : 利用树状数组的find_k_th实现找到sum为k的最小位置, 
 时间复杂度为O(log(n))
 ******************************************************************************/
#ifdef _MSC_VER
#define DEBUG
#endif

#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <limits.h>
#include <algorithm>
#include <stack>
#include <math.h>
#define MAX 50010
#define lowbit(x) (x&(-x))
using namespace std;

int c[MAX];
stack<int> order;

int getsum(int x)
{
	int sum=0;
	for(int i=x;i>0;i-=lowbit(i))
			sum+=c[i];
	return sum;
}

void updata(const int &x,const int &n, const int &val)
{
	for(int i=x;i<=n;i+=lowbit(i))
		c[i]+=val;
}

//找第k小的位置
int find_k_th(int k,const int &n, const int &logn) 
{
  int cnt=0,cur=0;
  for (int i=logn;i>=0;--i) {
    cur+=(1<<i); 
    if (cur>n || cnt+c[cur]>=k) cur-=(1<<i); 
    else cnt+=c[cur];
  }
  return cur+1;
}


int main(void)
{
#ifdef DEBUG  
  freopen("../stdin.txt","r",stdin);
  freopen("../stdout.txt","w",stdout); 
#endif  

  int n,m,x;
  char ch;

  while(~scanf("%d%d",&n,&m))
  {
	  memset(c,0,sizeof(c));
	  while(!order.empty())
		  order.pop();
    n+=2;
    updata(1,n,1);  //1号位和n+2号位用作哨兵, 只用[2,n+1]记录有效数据;
    updata(n,n,1);
    int logn = int(log(n+1.0)/log(2.0));
	  while(m--)
	  {
      getchar();
		  scanf("%c",&ch);
		  if(ch=='D')
      {
        scanf("%d",&x);
        ++x;
			  order.push(x);
			  updata(x,n,1);
		  }
		  else if(ch=='R')
		  {
			  x=order.top();
			  order.pop();
			  updata(x,n,-1);
		  }
		  else
		  {
        scanf("%d",&x); ++x;
        int sum=getsum(x),pre=find_k_th(sum,n,logn),next=find_k_th(sum+1,n,logn);
        if (pre!=x) printf("%d\n",next-pre-1);
        else printf("0\n");
      }
	  }
  }

	return 0;
}


你可能感兴趣的:(POJ2892 HDU 1540 Tunnel Warfare, 树状数组)