Link: http://www.lydsy.com/JudgeOnline/problem.php? Id = 1500
If you have done this, I will not say much.
There are a lot of notes and comments in the code
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; const int INF = ~ 0u> 2; # define l ch [x] [0] # define r ch [x] [1] # define kt (CH [CH [RT] [1] [0]) const int maxn = 500010; struct splaytree {int SZ [maxn]; int ch [maxn] [2]; int pre [maxn]; int RT, top, top2; int que [maxn], ss [maxn]; inline int max (int A, int B) {return A> B? A: B;} inline void down (INT X) {If (! X) return; If (FLIP [x]) {flip [l] ^ = 1; flip [R] ^ = 1; swap (L, R ); swap (LS [X], RS [x]); flip [x] = false;} If (same [x]) {// do not assign the value of 0 to If (l) Same [l] = 1; if (r) Same [R] = 1; if (l) val [l] = Val [X]; If (r) Val [R] = Val [X]; If (l) sum [l] = Val [x] * SZ [l]; If (r) sum [R] = Val [x] * SZ [R]; If (l) mx_sum [l] = ls [l] = Rs [l] = max (Val [X], sum [l]); If (r) mx_sum [R] = ls [R] = Rs [R] = max (Val [X], Sum [R]); same [x] = false ;}} inline void up (int x) {If (! X) return; If (l) Down (l); If (r) Down (r); // the key, the information of the son node must be down first, otherwise, the mx_sum may not be the real SZ [x] = 1 + SZ [l] + SZ [R]; sum [x] = Val [x] + sum [l] + sum [R]; LS [x] = max (LS [L], sum [l] + val [x] + max (LS [R], 0); RS [x] = max (RS [R], sum [R] + val [x] + max (RS [L], 0); mx_sum [x] = max (RS [L], 0) + val [x] + max (LS [R], 0); mx_sum [x] = max (mx_sum [X], max (mx_sum [L], mx_sum [R]);} inline void rotate (int x, int f) {int y = P Re [X]; down (y); down (x); ch [y] [! F] = CH [x] [f]; Pre [CH [x] [f] = y; Pre [x] = pre [y]; if (pre [x]) CH [pre [y] [CH [pre [y] [1] = y] = X; ch [x] [f] = y; Pre [y] = x; up (y);} inline void splay (int x, int goal) {// rotate X to the bottom of the goal down (x); // prevent pre [x] from being the target point. The following loop cannot be entered, the information of X cannot be passed down while (pre [x]! = Goal) {down (pre [pre [x]); down (pre [x]); down (x); // you need to upload the marker before rotation, because the node location may change if (pre [pre [x] = goal) rotate (x, CH [pre [x] [0] = X ); else {int y = pre [X], Z = pre [y]; int F = (CH [Z] [0] = y ); if (CH [y] [f] = x) rotate (x ,! F), rotate (x, f); else rotate (Y, F), rotate (x, f) ;}} up (x); If (Goal = 0) RT = x;} inline void RTO (int K, int goal) {// rotate the K-digit to int x = RT; down (x) under goal ); while (SZ [l] + 1! = K) {If (k <SZ [l] + 1) x = L; else {k-= (SZ [l] + 1); X = r ;} down (x);} splay (x, goal);} inline void newnode (Int & X, int C, int f) {If (top2) X = ss [-- top2]; else x = ++ top; L = r = 0; Pre [x] = f; SZ [x] = 1; val [x] = C; sum [x] = C; flip [x] = same [x] = false; ls [x] = Rs [x] = mx_sum [x] = C;} inline void build (Int & X, int L, int R, int F) {If (L> r) return; int M = L + r> 1; newnode (x, num [m], f); Build (L, l m-1, x); Build (R, m + 1, R, x); Pre [x] = f; up (x);} inline void debug () {vist (RT ); puts ("");} inline void Init (int n) {ch [0] [0] = CH [0] [1] = pre [0] = SZ [0] = 0; RT = Top = top2 = 0; flip [0] = false; Val [0] = 0; sum [0] = 0; same [0] = false; ls [0] = Rs [0] = mx_sum [0] =-INF; For (INT I = 1; I <= N; I ++) scanf ("% d", & num [I]); newnode (RT,-INF, 0); newnode (CH [RT] [1],-INF, RT ); SZ [RT] = 2; build (KT, 1, n, CH [RT] [1]); up (CH [RT] [1]); up (RT);} inline void erase (int x) {// Delete X as the ancestor node and put it into the memory pool to recycle the memory int father = pre [x]; int head = 0, tail = 0; For (que [tail ++] = x; head <tail; head ++) {ss [top2 ++] = que [head]; If (CH [que [head] [0]) que [tail ++] = CH [que [head] [0]; If (CH [que [head] [1]) que [tail ++] = CH [que [head] [1];} ch [Father] [CH [Father] [1] = x] = 0; up (father);} void vist (int x) {If (x) {printf ("Node % 2D: Left son % 2D right son % 2D VAL: % 5d mxsum: % 5d flip: % 5d same: % d \ n ", X, L, R, Val [X], mx_sum [X], flip [X], same [x]); vist (l); vist (r) ;}} inline void get_sum () {scanf ("% d", & Pos, & ToT ); int L = POs, r = POS + tot-1; RTO (L, 0); RTO (R + 2, RT); printf ("% d \ n ", sum [Kt]);} inline void Delete () {scanf ("% d", & Pos, & ToT); int L = POs, r = tot + pos-1; RTO (L, 0); RTO (R + 2, RT); erase (KT); KT = 0; up (CH [RT] [1]); up (RT);} inline void insert () {scanf ("% d", & Pos, & ToT); For (INT I = 1; I <= tot; I ++) scanf ("% d", & num [I]); RTO (Pos + 1, 0); RTO (Pos + 2, RT); Build (KT, 1, tot, CH [RT] [1]); up (CH [RT] [1]); up (RT);} inline void make_same () {int C; scanf ("% d", & Pos, & tot, & C); int L = POs, r = POS + tot-1; RTO (L, 0); RTO (R + 2, RT); same [Kt] = true; Val [Kt] = C; sum [Kt] = SZ [Kt] * C; mx_sum [Kt] = max (C, sum [Kt]); LS [Kt] = max (C, sum [Kt]); RS [Kt] = max (C, sum [Kt, sum [Kt]); up (CH [RT] [1]); up (RT);} void print (int x) {If (x) {down (X ); print (l); If (Val [x]>-10000) {If (FLAG) printf (""); printf ("% d", Val [x]); flag = 1;} print (r) ;}} inline void out () {flag = 0; print (RT); printf ("\ n ");} inline void reverse () {scanf ("% d", & Pos, & ToT); int L = POs, r = POS + tot-1; RTO (L, 0); RTO (R + 2, RT); flip [Kt] ^ = 1;} inline void max_sum () {RTO (1, 0); RTO (SZ [RT], RT); printf ("% d \ n", mx_sum [Kt]);} int flag; int POs, TOT; bool flip [maxn]; int Val [maxn]; int num [maxn]; int sum [maxn]; // sum bool same [maxn]; // replace it with a number of int ls [maxn]; // maximum prefix and INT Rs [maxn]; // maximum suffix and INT mx_sum [maxn]; // maximum subcolumn and} SPT; int main () {int n, m, POs, TOT; scanf ("% d", & N, & M); SPT. init (n); char op [50]; while (M --) {scanf ("% s", OP); If (strcmp (OP, "get-sum ") = 0) {SPT. get_sum ();} else if (strcmp (OP, "MAX-SUM") = 0) {SPT. max_sum ();} else if (strcmp (OP, "insert") = 0) {SPT. insert ();} else if (strcmp (OP, "delete") = 0) {SPT. delete ();} else if (strcmp (OP, "make-same") = 0) {SPT. make_same ();} else if (strcmp (OP, "out") = 0) {SPT. out ();} else if (strcmp (OP, "debug") = 0) {SPT. debug ();} else if (strcmp (OP, "newtree") = 0) {SPT. debug ();} else {SPT. reverse () ;}} return 0 ;}