又是找区间最长的什么什么的。和hotel前期处理差不多。都需要记录从左边开始的连续的最大值,从右边开始的连续最大值,以及整个区间的最大值。
不同的是,这个题的R D操作都是基于点的操作,所以不需要用 lazy思想了,直接更新到底。
至于查询,纠结了,参考了别人的代码,我发现我脑子还是有点转不过来哎。。。其实那种做法也想到了,就是感觉有点麻烦 = =。。。
注意查询临界情况,已经摧毁的用栈存了即可。
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
using namespace std;
const int MAX = 50010;
struct Tnode{ int cover,l,r,lval,rval,sum;};
Tnode node[MAX<<2];
stack<int> s;
void init()
{
memset(node,0,sizeof(node));
}
void Build(int t,int l,int r)
{
node[t].l = l; node[t].r = r;
node[t].lval = node[t].rval = node[t].sum = r - l;
node[t].cover = 1;
if( l == r - 1 ) return ;
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
}
void Updata_sum(int t)
{
if( node[R(t)].cover == 0 && node[L(t)].cover == 0 )
node[t].cover = 0;
else
if( node[R(t)].cover == 1 && node[L(t)].cover == 1 )
node[t].cover = 1;
else
node[t].cover = -1;
node[t].lval = node[L(t)].lval + ( node[L(t)].cover == 1 ? node[R(t)].lval : 0 );
node[t].rval = node[R(t)].rval + ( node[R(t)].cover == 1 ? node[L(t)].rval : 0 );
node[t].sum = max(node[t].rval,max(node[t].lval,node[L(t)].rval + node[R(t)].lval));
}
void Updata(int t,int l,int r,int val)
{
if( node[t].l >= l && node[t].r <= r )
{
node[t].cover = node[t].lval = node[t].rval = node[t].sum = val;
return ;
}
if( node[t].l == node[t].r - 1 ) return ;
int mid = MID(node[t].l,node[t].r);
if( l <= mid )
Updata(L(t),l,r,val);
if( r > mid )
Updata(R(t),l,r,val);
Updata_sum(t);
}
int Query(int t,int l)
{
if( node[t].cover == 1 ) return node[t].sum;
if( node[t].cover == 0 ) return 0;
int mid = MID(node[t].l,node[t].r);
if( l < mid )
{
if( mid - l <= node[L(t)].rval )
return node[L(t)].rval + node[R(t)].lval;
return Query(L(t),l);
}
else
{
if( l - mid + 1 <= node[R(t)].lval )
return node[L(t)].rval + node[R(t)].lval;
return Query(R(t),l);
}
}
int main()
{
int n,m,x;
char ch[2];
while( ~scanf("%d%d",&n,&m) )
{
init();
Build(1,0,n);
while( !s.empty() ) s.pop();
while( m-- )
{
scanf("%s",ch);
if( ch[0] == 'D' )
{
scanf("%d",&x);
Updata(1,x-1,x,0);
s.push(x);
}
if( ch[0] == 'R' )
{
if( s.empty() ) break;
x = s.top(); s.pop();
Updata(1,x-1,x,1);
}
if( ch[0] == 'Q' )
{
scanf("%d",&x);
int ans = Query(1,x-1);
printf("%d\n",ans);
}
}
}
return 0;
}