POJ2892 HDU 1540 Tunnel Warfare, 树状数组

来源:互联网 发布:java分布式开源发框架 编辑:程序博客网 时间:2024/05/18 22:15

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

/******************************************************************************* # Author : Neo Fung # Email : neosfung@gmail.com # 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;}


原创粉丝点击