/*************************************** * ****** The subject is as follows: there is a hotel with N rooms in a row. There are two operations: first, a customer wants to stay in a consecutive room; and the location of the smallest left endpoint must be output, if the number is not met, 0 is output. The second is to empty the continuous room with the length of B starting from a. 1 a: ask if there is an empty room with the continuous length of a. If yes, enter the leftmost room; 2 a B: Empty the room of [a, a + b-1]; algorithm thought: record the longest empty room lsum in the interval represents the number of consecutive vacancies on the left of the interval; rsum indicates the number of consecutive vacancies on the right of the interval; msum indicates the length of the maximum vacancy in the interval; algorithm process: If 1 ~ If the msum value of n ranges is smaller than x, there is no solution; otherwise, there is a solution. For each interval, if its left son's msum value is greater than or equal to x, it is searched in the left son; if the rsum of the Left son plus the lsum of the right son is greater than or equal to x, the right endpoint of the Left son is directly returned minus the rsum value of the Left son; otherwise, it is found in the right son; **************************************** * *****/# include <iostream> # include <cstring> # include <cstdlib> # include <cstdio> # include <climits> # include <algorithm> using namespace std; # define L l, m, u <1 # define R m + 1, r, u <1 | 1 const int N = 55555; int lsum [N <2]; // number of consecutive vacancies on the left of the interval; int r Sum [N <2]; // the number of consecutive vacancies on the right of the interval; int msum [N <2]; // the maximum length of a vacancy on the interval; int cover [N <2]; void PushDown (int u, int m) // update the information of the current node to the son node {if (cover [u]! =-1) {cover [u <1] = cover [u <1 | 1] = cover [u]; msum [u <1] = lsum [u <1] = rsum [u <1] = cover [u]? 0: m-(m> 1 ); msum [u <1 | 1] = lsum [u <1 | 1] = rsum [u <1 | 1] = cover [u]? 0: (m> 1); cover [u] =-1 ;}} void PushUp (int u, int m) // update the information of the current node to the parent node {lsum [u] = lsum [u <1]; rsum [u] = rsum [u <1 | 1]; if (lsum [u] = m-(m> 1) lsum [u] + = lsum [u <1 | 1]; if (rsum [u] = (m> 1) rsum [u] + = rsum [u <1]; msum [u] = max (lsum [u <1 | 1] + rsum [u <1], max (msum [u <1], msum [u <1 | 1]);} void build (int l, int r, int u) {msum [u] = lsum [u] = rsum [u] = r-l + 1; cover [u] =-1; if (l = r) return; Int m = (l + r)> 1; build (L); build (R);} void update (int l1, int r1, int c, int l, int r, int u) // replace {if (l1 <= l & r <= r1) {msum [u] = lsum [u] = rsum [u] = c? 0: r-l + 1; cover [u] = c; return;} PushDown (u, r-l + 1); int m = (l + r)> 1; if (l1 <= m) update (l1, r1, c, L); if (m <r1) update (l1, r1, c, R ); pushUp (u, r-l + 1);} int query (int w, int l, int r, int u) // query the leftmost breakpoint that meets the condition {if (l = r) return l; PushDown (u, r-l + 1 ); int m = (l + r)> 1; if (msum [u <1]> = w) // The msum value of the Left son is greater than or equal to x, return query (w, L); else if (rsum [u <1] + lsum [u <1 | 1]> = w) // If the rsum of the Left son plus the lsum of the right son is greater than or equal to x, the right endpoint of the Left son is directly returned minus the rsum value of the Left son; return m-rsum [u <1] + 1; return query (w, R); // otherwise, go to the right son to find it;} int main () {// freopen ("C: \ Users \ Administrator \ Desktop \ kd.txt", "r", stdin); int n, m; scanf ("% d", & n, & m); build (1, n, 1); while (m --) {int op, a, B; scanf ("% d", & op); if (op = 1) {scanf ("% d", & a); if (msum [1] <) puts ("0"); else {int p = query (a, 1, n, 1); printf ("% d \ n", p); update (p, p + a-1, 1, 1, n, 1) ;}} else {scanf ("% d", & a, & B); update (, a + B-1, 0, 1, n, 1) ;}} return 0 ;}