Esta pregunta es un buen problema.
La actualización con el siguiente valor más pequeño y el valor mínimo, WA por un largo tiempo.
Esta pregunta se utiliza en el análisis de la práctica potencial de energía, y no utilizar el Monitor de CPU que pregunta en el proceso de marcado.
Tener tiempo para mirar las similitudes y diferencias entre estos tipos de línea de árboles.
código:
# include <cstdio> #include <algoritmo> #include <cstring> #include <math> #define ll mucho tiempo #define N 500006 # define LSON x << 1 #define rson x << 1 | 1 # define inf 0x3f3f3f3f # definir I (s) freopen (s ".En", "r", stdin) #define O (s) freopen (s ".out", "w", stdout) #define setIO (s) I (s), O (s) usando namespace std; int Nmin [N << 2], Pmin [N << 2], se [N << 2]; int ptag_a [N << 2], ntag_a [N << 2], ptag_b [N << 2], ntag_b [N << 2]; void pushup (int x) { Nmin [x] = min (Nmin [LSON], Nmin [rson]); si (Nmin [rson] <Nmin [impuesto LSON]) [x] = min (SE [rson], Nmin [LSON]); si (Nmin [LSON] == Nmin [impuesto rson]) [x] = min (SE [impuesto LSON], [rson]); } // v1表示历史最小 void mark_a (int x, int v1, v2 int) { Pmin [x] = min (Pmin [x], Nmin [x] + v1); ptag_a [x] = min (ptag_a [x], ntag_a [x] + v1); Nmin [x] + = v2, ntag_a [x] + = v2; } Mark_b Void (int x, int v1, v2 int) { ptag_b [x] = min (ptag_b [x], ntag_b [x] + v1); ntag_b [x] + = v2; si (SE [x] = INF impuestos!) [x] + = v2; } Pushdown Void (int x) { int c = min (Nmin [LSON], Nmin [rson]); si (Nmin [LSON] == c) { mark_a (LSON, ptag_a [x], ntag_a [x]); mark_b (LSON, ptag_b [x], ntag_b [x]); } Else { mark_a (LSON, ptag_b [x], ntag_b [x]); mark_b (LSON, ptag_b [x], ntag_b [x]); } Si (Nmin [rson] == c) { mark_a (rson, ptag_a [x], ntag_a [x]); mark_b (rson, ptag_b [x], ntag_b [x]); } Else { mark_a (rson, ptag_b [x], ntag_b [x]); mark_b (rson, ptag_b [x], ntag_b [x]); } ptag_a [x] = ntag_a [x] = ptag_b [x] = ntag_b [x] = 0; } Addv Void (int l, r int, int x, int L, R int, v int) { Si (l> = L && r <= R) { mark_a (x, v, v), mark_b (x, v, v); regreso; } Pushdown (x); int mediados = (l + r) >> 1; si (L <= centro) addv (l, mediados, LSON, L, R, v); Si (R> MID) addv (mediados + 1, r, rson, L, R, v); pushup (x); } Void GetMax (int l, r int, int x, int L, int R, int v) { si (Nmin [x]> = v) de retorno; si (l> = L && r <= R && SE [x]> v) { mark_a (x, v-Nmin [x], v-Nmin [x]); regreso; } Pushdown (x); si (L <= centro) GetMax (l, mediados, LSON, L, R, v); Si (R> MID) GetMax (mediados + 1, r, rson, L, R, v); pushup (x); } Int queryn (int l, r int, int x, int L, int R) { si (l> = L && r <= R) de retorno Nmin [x]; pushdown (x); int mediados = (l + r) >> 1; si (L <= mediados && R> mediados) return min (queryn (l, mediados, LSON, L, R), queryn (mediados + 1, r, rson, L, R)); else if (L <= centro) de retorno queryn (l, mediados, LSON, L, R); queryn retorno más (mediados + 1, r, rson, L, R); } Int queryp (int l, r int, int x, int L, int R) { si (l> = L && r <= R) de retorno pmin [x]; pushdown (x); int mediados = (l + r) >> 1; si (L <= mediados && R> mediados) return min (queryp (l, mediados, LSON, L, R), queryp (mediados + 1, r, rson, else if (L <= centro) de retorno queryp (l, mediados, LSON, L, R); queryp retorno más (mediados + 1, r, rson, L, R); si (op == 1) scanf ( "% d", y { Si (l == r) { scanf ( "% d", y Nmin [x]), Pmin [x] = Nmin [x], SE [x] = inf; regreso; } Int mediados = (l + r) >> 1; build (l, mediados, LSON), build (mediados + 1, r, rson); pushup (x); } Int main () { // setIO ( "input"); int n, m; scanf ( "% d% d", y n, y m), de construcción (1, n, 1); for (int i = 1; i <= m; ++ i) { int op, l, r, z; scanf ( "% d% d% d", & OP, & l, y r); si (op == 2) scanf ( "% d", y z), GetMax (1, n, 1, l, r, z); si (op == 3) printf ( "% d \ n", queryn (1, n, 1, l, r)); } Return 0; }