还不错的一道线段树区间合并。挺巧妙的用法。
1 /* 1540 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxn = 50005; 43 int ls[maxn<<2], rs[maxn<<2], ms[maxn<<2]; 44 int S[maxn], top; 45 46 void Build(int l, int r, int rt) { 47 ls[rt] = rs[rt] = ms[rt] = r - l + 1; 48 if (l == r) 49 return ; 50 51 int mid = (l + r) >> 1; 52 Build(lson); 53 Build(rson); 54 } 55 56 void PushUp(int l, int r, int rt) { 57 int mid = (l + r) >>1; 58 int lb = rt<<1; 59 int rb = lb |1; 60 61 ls[rt] = ls[lb]; 62 rs[rt] = rs[rb]; 63 if (ls[lb] == mid-l+1) 64 ls[rt] += ls[rb]; 65 if (rs[rb] == r-mid) 66 rs[rt] += rs[lb]; 67 68 ms[rt] = max(ms[lb], ms[rb]); 69 ms[rt] = max(ms[rt], rs[lb]+ls[rb]); 70 } 71 72 void update(int x, int delta, int l, int r, int rt) { 73 if (l == r) { 74 ls[rt] = rs[rt] = ms[rt] = delta; 75 return ; 76 } 77 78 int mid = (l + r) >> 1; 79 80 if (x <= mid) { 81 update(x, delta, lson); 82 } else { 83 update(x, delta, rson); 84 } 85 86 PushUp(l, r, rt); 87 } 88 89 int Query(int x, int l, int r, int rt) { 90 if (l==r || ms[rt]==0 || ms[rt]==r-l+1) 91 return ms[rt]; 92 93 int mid = (l + r) >> 1; 94 int lb = rt<<1; 95 int rb = lb |1; 96 97 if (x <= mid) { 98 if (x >= mid-rs[lb]+1) { 99 return Query(x, lson) + Query(mid+1, rson); 100 } else { 101 return Query(x, lson); 102 } 103 } else { 104 if (x <= mid+ls[rb]) { 105 return Query(mid, lson) + Query(x, rson); 106 } else { 107 return Query(x, rson); 108 } 109 } 110 } 111 112 int main() { 113 ios::sync_with_stdio(false); 114 #ifndef ONLINE_JUDGE 115 freopen("data.in", "r", stdin); 116 freopen("data.out", "w", stdout); 117 #endif 118 119 int n, m, x; 120 char cmd[5]; 121 int ans; 122 123 while (scanf("%d %d", &n, &m)!=EOF) { 124 Build(1, n, 1); 125 top = 0; 126 while (m--) { 127 scanf("%s", cmd); 128 if (cmd[0] == 'D') { 129 scanf("%d", &x); 130 S[top++] = x; 131 update(x, 0, 1, n, 1); 132 } else if (cmd[0] == 'Q') { 133 scanf("%d", &x); 134 ans = Query(x, 1, n, 1); 135 printf("%d ", ans); 136 } else { 137 if (top > 0) { 138 x = S[--top]; 139 update(x, 1, 1, n, 1); 140 } 141 } 142 } 143 } 144 145 #ifndef ONLINE_JUDGE 146 printf("time = %d. ", (int)clock()); 147 #endif 148 149 return 0; 150 }