题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
思路:只需要求左半区间被毁村庄的最大值,和右边区间被毁村庄的最小值
注意,答案有两种方式
AC代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define inf 0xfffffff
#define MAX 50005
#define lson l,m,c<<1
#define rson m+1,r,c<<1|1
using namespace std;
int treel[MAX<<2];
int treer[MAX<<2];
int n,m;
int history[MAX<<2];
void pushup(int c)
{
treel[c]=max(treel[c<<1],treel[c<<1|1]);
treer[c]=min(treer[c<<1],treer[c<<1|1]);
}
void build(int l,int r,int c)
{
if(l==r)
{
treel[c]=0;
treer[c]=n+1;
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(c);
}
void update(int p,int q,int l,int r,int c)
{
if(l==r)
{
if(q==0)
treel[c]=q;
else if(q==n+1)
treer[c]=q;
else{
treel[c]=q;
treer[c]=q;
}
return;
}
int m=(l+r)>>1;
if(p<=m) update(p,q,lson);
else update(p,q,rson);
pushup(c);
}
int query_l(int ll,int rr,int l,int r,int c)
{
if(ll<=l&&rr>=r)
{
return treel[c];
}
int m=(l+r)>>1;
int ret=0;
if(ll<=m) ret=max(ret,query_l(ll,rr,lson));
if(rr>m) ret=max(ret,query_l(ll,rr,rson));
return ret;
}
int query_r(int ll,int rr,int l,int r,int c)
{
if(ll<=l&&rr>=r)
{
return treer[c];
}
int m=(l+r)>>1;
int ret=inf;
if(ll<=m) ret=min(ret,query_r(ll,rr,lson));
if(rr>m) ret=min(ret,query_r(ll,rr,rson));
return ret;
}
int main()
{
int num;
while(scanf("%d%d",&n,&m)!=EOF)
{
char op[10];
int count =0;
int i,j;
int a,b;
memset(history,0,sizeof(history));
// memset(sum,0,sizeof(sum));
build(1,n,1);
for(i=1;i<=m;i++)
{
scanf("%s",op);
if(op[0]=='R')
{
int temp=history[--count];
update(temp,0,1,n,1);
update(temp,n+1,1,n,1);
}
else if(op[0]=='D')
{
scanf("%d",&a);
update(a,a,1,n,1);
history[count++]=a;
}
else
{
scanf("%d",&a);
int _max,_min;
_max=query_l(1,a,1,n,1);
_min=query_r(a,n,1,n,1);
if(_max-_min==0) printf("0\n");
else printf("%d\n",_min-_max-1);
}
}
}
return 0;
}