~~~~
Merge line segment tree intervals ~
Two operations:
1. The output satisfies the leftmost value of the continuous interval.
2. Update a continuous interval.
Question link: http://poj.org/problem? Id = 3667
~~~~
# Include <cstdio> # include <cstring> # include <algorithm> # define INF 0x7fffffff # define lson RT <1, S, M # define rson RT <1 | 1, m + 1, e # define n 55555 using namespace STD; struct node {int V; int LM, RM, Sm;} tre [n <2]; void build (int rt, int S, int e) {tre [RT]. V =-1; tre [RT]. lm = tre [RT]. rm = tre [RT]. sm = e-S + 1; if (S = e) return; int M = (S + E)> 1; build (lson); Build (rson );} void Pushdown (int rt, int m) // segment update operation. {If (Tre [RT]. V! =-1) {tre [RT <1]. V = tre [RT <1 | 1]. V = tre [RT]. v; tre [RT <1]. lm = tre [RT <1]. rm = tre [RT <1]. sm = tre [RT]. v? 0: M-(M> 1); tre [RT <1 | 1]. lm = tre [RT <1 | 1]. rm = tre [RT <1 | 1]. sm = tre [RT]. v? 0: m> 1; tre [RT]. V =-1 ;}} void pushup (int rt, int m) // merge intervals. {Tre [RT]. lm = tre [RT <1]. lm; tre [RT]. rm = tre [RT <1 | 1]. rm; If (Tre [RT]. lm = m-(M> 1) tre [RT]. lm + = tre [RT <1 | 1]. lm; If (Tre [RT]. rm = (M> 1) tre [RT]. RM + = tre [RT <1]. rm; tre [RT]. sm = max (Tre [RT <1]. SM, max (Tre [RT <1 | 1]. SM, tre [RT <1]. RM + tre [RT <1 | 1]. lm);} int query (int n, int RT, int S, int e) {If (S = e) return s; Pushdown (RT, e-S + 1); int M = (S + E)> 1; // The leftmost position is output. If (Tre [RT <1]. sm> = N) return query (n, lson); else if (Tre [RT <1]. RM + tre [RT <1 | 1]. lm> = N) return M-Tre [RT <1]. RM + 1; // the middle area of the two subintervals. Else return query (n, rson);} void Update (int l, int R, int V, int RT, int S, int e) {If (L = S & R = e) {tre [RT]. V = V; tre [RT]. lm = tre [RT]. rm = tre [RT]. sm = V? 0: E-S + 1; return;} Pushdown (RT, e-S + 1); int M = (S + E)> 1; if (r <= m) Update (L, R, V, lson); else if (L> m) Update (L, R, V, rson ); else {Update (L, M, V, lson); Update (m + 1, R, V, rson);} pushup (RT, e-S + 1 );} int main () {int n, m; while (~ Scanf ("% d", & N, & M) {build (1,1, n); For (INT I = 0; I <m; I ++) {int op; scanf ("% d", & OP); If (OP = 1) {int num; scanf ("% d", & num ); if (Tre [1]. sm> = num) {int K = query (Num, n); printf ("% d \ n", k); Update (K, K + num-1, 1, n);} else puts ("0");} else {int K, num; scanf ("% d", & K, & num ); update (K, K + num-1, 1, n) ;}} return 0 ;}