又是找区间最长的什么什么的。和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; }