题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2871
这个题目与线段树区间合并的模板题(链接:点这里)非常相似,就是复杂了一点;
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<vector>
5 #include<map>
6 #include<queue>
7 #include<set>
8 #include<cmath>
9 #include<list>
10 #include<cstring>
11 #include<string>
12 #define ll long long
13 #define ull unsigned long long
14 #define inf 0x3f3f3f3f
15 #define inff 0x7fffffff
16 using namespace std;
17 const int N = 50000 + 10;
18 const int M = 1000000 + 10;
19 const ll mod = 1e9 + 7;
20
21 struct node {
22 int lsum;
23 int rsum;
24 int sum;
25 int lazy;
26 int len;
27 }tree[N << 2];
28
29 void PushUp(int rt) {
30
31 if (tree[rt << 1].sum == tree[rt << 1].len) {
32 tree[rt].lsum = tree[rt << 1].sum + tree[rt << 1 | 1].lsum;
33 }
34 else {
35 tree[rt].lsum = tree[rt << 1].lsum;
36 }
37 if (tree[rt << 1 | 1].sum == tree[rt << 1 | 1].len) {
38 tree[rt].rsum = tree[rt << 1 | 1].sum + tree[rt << 1].rsum;
39 }
40 else {
41 tree[rt].rsum = tree[rt << 1 | 1].rsum;
42 }
43 tree[rt].sum = tree[rt << 1].rsum + tree[rt << 1 | 1].lsum;
44 tree[rt].sum = max(tree[rt << 1].sum, tree[rt].sum);
45 tree[rt].sum = max(tree[rt << 1 | 1].sum, tree[rt].sum);
46
47 return;
48 }
49
50 void Build(int l, int r, int rt) {
51
52 tree[rt].len = r - l + 1;
53 if (l == r) {
54 tree[rt].sum = tree[rt].lsum = tree[rt].rsum = 1;
55 return;
56 }
57 int mid = (l + r) >> 1;
58 Build(l, mid, rt << 1);
59 Build(mid + 1, r, rt << 1 | 1);
60 PushUp(rt);
61
62 return;
63 }
64
65 void PushDown(int l, int r, int rt) {
66
67 if (tree[rt].lazy == 0) return;
68 int mid = (l + r) >> 1;
69 if (tree[rt].lazy == 1) {
70 tree[rt << 1].sum = tree[rt << 1].lsum = tree[rt << 1].rsum = 0;
71 tree[rt << 1 | 1].sum = tree[rt << 1 | 1].lsum = tree[rt << 1 | 1].rsum = 0;
72 tree[rt << 1].lazy = tree[rt << 1 | 1].lazy = 1;
73 }
74 else {
75 tree[rt << 1].sum = tree[rt << 1].lsum = tree[rt << 1].rsum = mid - l + 1;
76 tree[rt << 1 | 1].sum = tree[rt << 1 | 1].lsum = tree[rt << 1 | 1].rsum = r - (mid + 1) + 1;
77 tree[rt << 1].lazy = tree[rt << 1 | 1].lazy = 2;
78 }
79 tree[rt].lazy = 0;
80
81 return;
82 }
83
84 void Update_in(int L, int R, int l, int r, int rt) {
85
86 if (l >= L && r <= R) {
87 tree[rt].sum = tree[rt].lsum = tree[rt].rsum = 0;
88 tree[rt].lazy = 1;
89 return;
90 }
91 PushDown(l, r, rt);
92 int mid = (l + r) >> 1;
93 if (L <= mid) Update_in(L, R, l, mid, rt << 1);
94 if (R > mid) Update_in(L, R, mid + 1, r, rt << 1 | 1);
95 PushUp(rt);
96
97 return;
98 }
99
100 void Update_out(int L, int R, int l, int r, int rt) {
101
102 if (l >= L && r <= R) {
103 tree[rt].sum = tree[rt].lsum = tree[rt].rsum = r - l + 1;
104 tree[rt].lazy = 2;
105 return;
106 }
107 PushDown(l, r, rt);
108 int mid = (l + r) >> 1;
109 if (L <= mid) Update_out(L, R, l, mid, rt << 1);
110 if (R > mid) Update_out(L, R, mid + 1, r, rt << 1 | 1);
111 PushUp(rt);
112
113 return;
114 }
115
116 //void PointUpdate(int L, int l, int r, int rt) {
117 //
118 // if (l == r) {
119 // sum[rt]++;
120 // return;
121 // }
122 // int mid = (l + r) >> 1;
123 // if (L <= mid) PointUpdate(L, l, mid, rt << 1);
124 // else PointUpdate(L, mid + 1, r, rt << 1 | 1);
125 // PushUp(rt);
126 //
127 // return;
128 //}
129
130 int Query(int len, int l, int r, int rt) {
131
132 if (l == r) return l;
133 int mid = (l + r) >> 1;
134 PushDown(l, r, rt);
135 if (tree[rt << 1].sum >= len) {
136 return Query(len, l, mid, rt << 1);
137 }
138 if (tree[rt << 1].rsum + tree[rt << 1 | 1].lsum >= len) {
139 return mid - tree[rt << 1].rsum + 1;
140 }
141 if (tree[rt << 1 | 1].sum >= len) {
142 return Query(len, mid + 1, r, rt << 1 | 1);
143 }
144
145 return 0;
146 }
147
148 //int Query(int L, int R, int l, int r, int rt) {
149 //
150 // if (l >= L && r <= R) {
151 // return sum[rt];
152 // }
153 // int mid = (l + r) >> 1;
154 //
155 // int ans = 0;
156 // if (L <= mid) ans += Query(L, R, l, mid, rt << 1);
157 // if (R > mid) ans += Query(L, R, mid + 1, r, rt << 1 | 1);
158 //
159 // return ans;
160 //}
161
162 struct section {
163 int st, end;
164 bool operator <(const section& b)const {
165 return st < b.st;
166 }
167 };
168
169 vector<section>vec;
170
171 bool cmp(section a, section b) {
172 if (a.st <= b.st) return true;
173 else return false;
174 }
175
176 int FindPos(int x, int l, int r) {
177
178 int pos = -1;
179 int lx = l, rx = r;
180 while (lx <= rx) {
181 int mid = (lx + rx) >> 1;
182 if (x >= vec[mid].st) {
183 pos = mid;
184 lx = mid + 1;
185 }
186 else {
187 rx = mid - 1;
188 }
189 }
190 if (vec[pos].st > x || vec[pos].end < x) {
191 return -1;
192 }
193 else return pos;
194 }
195
196 int main() {
197
198 /*ios::sync_with_stdio(false);
199 cin.tie(0);*/
200 int n, m;
201 while (~scanf("%d %d", &n, &m)) {
202 Build(1, n, 1);
203 for (int i = 1; i <= m; i++) {
204 char op[10];
205 int x;
206 scanf("%s", op);
207 if (op[0] == 'N') {
208 scanf("%d", &x);
209 int pos = Query(x, 1, n, 1);
210 if (pos != 0) {
211 //vec.push_back({ pos,pos + x - 1 });
212 section t;
213 t.st = pos, t.end = pos + x - 1;
214 vector<section>::iterator it;
215 it = upper_bound(vec.begin(), vec.end(), t);
216 vec.insert(it, t);
217 Update_in(pos, pos + x - 1, 1, n, 1);
218 //cout << "New at " << pos << "\n";
219 printf("New at %d\n", pos);
220 }
221 else printf("Reject New\n");
222 //cout << "Reject New" << "\n";
223 }
224 else if (op[0] == 'F') {
225 scanf("%d", &x);
226 //sort(vec.begin(), vec.end(), cmp);
227 int pos = -1;
228 //int pos = upper_bound(vec.begin(), vec.end(), x) - vec.begin();
229 int l = 0, r = vec.size() - 1;
230 pos = FindPos(x, l, r);
231 if (pos == -1) {
232 //cout << "Reject Free" << "\n";
233 printf("Reject Free\n");
234 }
235 else {
236 Update_out(vec[pos].st, vec[pos].end, 1, n, 1);
237 vector<section>::iterator it;
238 it = vec.begin() + pos;
239 printf("Free from %d to %d\n", vec[pos].st, vec[pos].end);
240 //cout << "Free from " << vec[pos].st << " to " << vec[pos].end << "\n";
241 vec.erase(it);
242 }
243 }
244 else if (op[0] == 'G') {
245 scanf("%d", &x);
246 if (x > vec.size()) {
247 //cout << "Reject Get" << "\n";
248 printf("Reject Get\n");
249 continue;
250 }
251 //sort(vec.begin(), vec.end(), cmp);
252 //cout << "Get at " << vec[x - 1].st << "\n";
253 printf("Get at %d\n", vec[x - 1].st);
254 }
255 else {
256 Update_out(1, n, 1, n, 1);
257 vec.clear();
258 //cout << "Reset Now" << "\n";
259 printf("Reset Now\n");
260 }
261 /*cout << "---------------------------------" << "\n";
262 for (int i = 0; i < vec.size(); i++) {
263 cout << vec[i].st << " " << vec[i].end << "\n";
264 }
265 cout << "---------------------------------" << "\n";*/
266 }
267 putchar('\n');
268 vec.clear();
269 memset(tree, 0, sizeof(tree));
270 }
271
272 return 0;
273 }