1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <iostream> #include <algorithm> #include <stack> using namespace std; const int maxn = 5e4+5; int n,m; int num[maxn]; struct segement { int len, leftlen, rightlen; #define len(x) tree[x].len #define leftlen(x) tree[x].leftlen #define rightlen(x) tree[x].rightlen }tree[4*maxn]; void pushUp(int p,int left,int right) { len(p) = max(len(2*p),len(2*p+1)); //左子树和右子树长度最大值 len(p) = max(len(p),rightlen(2*p)+leftlen(2*p+1)); // 或者是左子树右边连续+右子树左边连续 leftlen(p) = leftlen(2 * p); //父亲节点的最大左边长度是左子节点左边长度 rightlen(p) = rightlen(2 * p + 1); int mid = (left + right)/2; // 如果左子树是连续的,那么父节点左子树的值=左子树+右子树左端长度 if (leftlen(p) == mid - left + 1) leftlen(p) += leftlen(2*p+1); if (rightlen(p) == right - mid) rightlen(p) += rightlen(2*p); } void build(int p,int left,int right) { if (left == right) { len(p) = leftlen(p) = rightlen(p) = 1; return; } int mid = (left + right) / 2; build(2*p,left,mid); build(2*p+1,mid+1,right); pushUp(p,left,right); } void update(int p,int left,int right,int index,int val) { if (left == right && right == index) { //找到叶节点 len(p) = leftlen(p) = rightlen(p) = val; return; } int mid = (left + right)/2; if (index <= mid) update(2*p,left,mid,index,val); else update(2*p+1,mid+1,right,index,val); pushUp(p,left,right); } int query(int p,int left,int right,int index) { if (len(p) == 0 || len(p) == right - left + 1) return len(p); int mid = (left + right) / 2; if (index <= mid) // index不在左子树最右连续区间内,继续递归查找,反之同理 return index > mid - rightlen(2*p) ? rightlen(2*p) + leftlen(2*p+1) : query(2*p,left,mid,index); return index <= mid + leftlen(2*p+1) ? leftlen(2*p+1) + rightlen(2*p) : query(2*p+1,mid+1,right,index); } int main() { // freopen("a.txt", "r", stdin); char ch[5]; int p; while (scanf("%d%d",&n,&m) != EOF) { stack<int> s; build(1, 1, n); while (m--) { scanf("%s",ch); if (ch[0] == 'R' && !s.empty()) { p = s.top(); s.pop(); update(1,1,n,p,1); } else if (ch[0] == 'D') { scanf("%d",&p); update(1, 1, n, p, 0); s.push(p); } else { scanf("%d",&p); printf("%d\n",query(1,1,n,p)); } } } return 0; }
|