题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
题目大意:给你一排连续的点,你可以进行下面三种操作:
1、删除一个点
2、询问和一个点所在段的长度(如果该点已删除,长度为0)
3、恢复上一个删除的点
线段树计算连续区间,结点保存该段左连续长度lm,和右连续长度rm
1 /* 2 * Problem: hdu 1540 Tunnel Warfare 3 * Author: SHJWUDP 4 * Created Time: 2015/3/28 星期六 13:10:49 5 * File Name: 233.cpp 6 * State: Accepted 7 * Memo: 线段树 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 16 const int MaxA=5e4+7; 17 18 struct SegmentTree { 19 //这个结构可以求最大连续区间,只需要加上一个变量保存当前节点下最大连续区间 20 struct Node { 21 int lm, rm; 22 Node(){} 23 Node(int l, int r):lm(l), rm(r){} 24 } *c; 25 int n; 26 int p, sign; 27 28 SegmentTree(int n):n(n) { 29 c=new Node[(n+7)<<2]; 30 build(1, n, 1); 31 } 32 ~SegmentTree() { 33 delete c; 34 } 35 #define INIT Node& u=c[rt]; Node& ls=c[rt<<1]; Node& rs=c[rt<<1|1]; 36 #define lson l, m, rt<<1 37 #define rson m+1, r, rt<<1|1 38 39 void pushUp(int l, int m, int r, int rt) { 40 INIT; 41 u=Node(ls.lm, rs.rm); 42 if(m-l+1==ls.lm) u.lm+=rs.lm; 43 if(r-m==rs.rm) u.rm+=ls.rm; 44 } 45 46 void build(int l, int r, int rt) { 47 if(l==r) { 48 c[rt]=Node(1, 1); 49 } else { 50 int m=(l+r)>>1; 51 build(lson); 52 build(rson); 53 pushUp(l, m, r, rt); 54 } 55 } 56 57 void doUpdate(int l, int r, int rt) { 58 if(l==r) { 59 c[rt]=sign?Node(1, 1):Node(0, 0); 60 } else { 61 int m=(l+r)>>1; 62 if(p<=m) doUpdate(lson); 63 else doUpdate(rson); 64 pushUp(l, m, r, rt); 65 } 66 } 67 68 void update(int p, int sign) { 69 this->p=p; this->sign=sign; 70 doUpdate(1, n, 1); 71 } 72 73 int doQuery(int l, int r, int rt) { 74 INIT; 75 if(p-l<u.lm || r-p<u.rm) { 76 return p-l<u.lm?u.lm:u.rm; 77 } else if(l==r) return 0; 78 else { 79 int m=(l+r)>>1; 80 int res=0; 81 if(p<=m) res+=doQuery(lson)+(m-p+1<=ls.rm?rs.lm:0); 82 else res+=doQuery(rson)+(p-m<=rs.lm?ls.rm:0); 83 return res; 84 } 85 } 86 87 int query(int p) { 88 this->p=p; 89 return doQuery(1, n, 1); 90 } 91 #undef INIT 92 #undef lson 93 #undef rson 94 }; 95 96 int n, m; 97 int stk[MaxA], top; 98 int main() { 99 #ifndef ONLINE_JUDGE 100 freopen("in", "r", stdin); 101 //freopen("out", "w", stdout); 102 #endif 103 while(~scanf("%d%d", &n, &m)) { 104 SegmentTree st(n); 105 top=0; 106 while(m--) { 107 char op[2]; 108 int x; 109 scanf("%s", op); 110 switch(op[0]) { 111 case 'D': 112 scanf("%d", &x); 113 st.update(stk[++top]=x, 0); 114 break; 115 case 'Q': 116 scanf("%d", &x); 117 printf("%d ", st.query(x)); 118 break; 119 case 'R': 120 st.update(stk[top--], 1); 121 break; 122 } 123 } 124 } 125 return 0; 126 }