[序列终结者]( Splay树 )
From:http://www.lydsy.com/JudgeOnline/problem.php?id=1251
Solution: 维护数列的简单版
/************************************************************** Problem: 1251 User: leezy Language: C++ Result: Accepted Time:9312 ms Memory:2840 kb ****************************************************************/ #include <iostream> #include <stdio.h> #include <string.h> #include <cmath> using namespace std; #define N 50015 #define M 1000000 #define INF (1<<29) struct SPLAY { int v,l,r,p,s,delta,rev,Max;} t[N]; int cnt,root; #define KT t[root].r void Dump(int x){ if ( x ){ printf("%d[v=%d,Max=%d,rev=%d,delta=%d][L=%d,R=%d]\n", x,t[x].v,t[x].Max,t[x].rev,t[x].delta,t[x].l,t[x].r); Dump(t[x].l); Dump(t[x].r); } } int NewNode(int v, int fa){ t[++cnt].v = t[cnt].Max = v; t[cnt].l = t[cnt].r = 0; t[cnt].delta = t[cnt].rev = 0; t[cnt].s = 1; t[cnt].p = fa; return cnt; } void Upd_Down(int x){ int L = t[x].l, R = t[x].r; if ( t[x].delta ){ t[x].v += t[x].delta; t[x].Max = max(t[x].Max+t[x].delta, t[x].v); if ( L ) t[L].delta += t[x].delta; if ( R ) t[R].delta += t[x].delta; t[x].delta = 0; } if ( t[x].rev ){ swap(t[x].l, t[x].r); if ( L ) t[L].rev ^= 1; if ( R ) t[R].rev ^= 1; t[x].rev = 0; } } void Upd_Up(int x){ if ( x ){ int L = t[x].l, R = t[x].r; if ( L ) Upd_Down(L); if ( R ) Upd_Down(R); t[x].s = t[L].s + t[R].s + 1; t[x].Max = max(t[L].Max, t[x].v); t[x].Max = max(t[R].Max, t[x].Max); } } int Build(int l, int r, int fa) { if ( l <= r ){ int mid = (l+r)>>1; int k = NewNode(0, fa); t[k].p = fa; t[k].l = Build(l, mid-1, k); t[k].r = Build(mid+1, r, k); Upd_Up(k); return k; } return 0; } void Rot_L(int x){ int y = t[x].r; Upd_Down(y); Upd_Down(x); t[x].r = t[y].l; t[t[y].l].p = x; t[y].p = t[x].p; if ( !t[x].p ) root = y; else if ( t[t[x].p].l == x ) t[t[x].p].l = y; else t[t[x].p].r = y; t[y].l = x; t[x].p = y; Upd_Up(x); Upd_Up(y); } void Rot_R(int x){ int y = t[x].l; Upd_Down(y); Upd_Down(x); t[x].l = t[y].r; t[t[y].r].p = x; t[y].p = t[x].p; if ( !t[x].p ) root = y; else if ( t[t[x].p].l == x ) t[t[x].p].l = y; else t[t[x].p].r = y; t[y].r = x; t[x].p = y; Upd_Up(x); Upd_Up(y); } void Splay(int x, int to){ Upd_Down(x); while ( t[x].p != to ){ int p1 = t[x].p; int p2 = t[p1].p; if ( t[p1].l == x ){ if ( p2 == to ) Rot_R(p1); else if ( t[p2].l == p1 ) Rot_R(p2), Rot_R(p1); else Rot_R(p1), Rot_L(p2); } else { if ( p2 == to ) Rot_L(p1); else if ( t[p2].r == p1 ) Rot_L(p2), Rot_L(p1); else Rot_L(p1), Rot_R(p2); } } Upd_Up(x); //Dump(root); printf("\n"); } int Get_Kth(int x, int k){ Upd_Down(x); int kk = t[t[x].l].s + 1; if ( kk == k ) return x; if ( kk < k ) return Get_Kth(t[x].r, k-kk); return Get_Kth(t[x].l, k); } void Modify(int l, int r, int v){ //printf("Modify\n"); int x = Get_Kth(root, l); int y = Get_Kth(root, r+2); Splay(x, 0); Splay(y, x); t[t[KT].l].delta += v; Upd_Down(t[KT].l); //Dump(root); printf("\n"); } void Reverse(int l, int r){ //printf("Reverse\n"); int x = Get_Kth(root, l); int y = Get_Kth(root, r+2); Splay(x, 0); Splay(y, x); t[t[KT].l].rev = 1; Upd_Down(t[KT].l); //Dump(root); printf("\n"); } int GetMax(int l, int r){ //printf("GetMax\n"); int x = Get_Kth(root, l); int y = Get_Kth(root, r+2); Splay(x, 0); Splay(y, x); //Dump(root); printf("\n"); return t[t[KT].l].Max; } void Init(int n){ cnt = root = 0; t[0].v = t[0].Max = -INF; t[0].delta = t[0].rev = 0; t[0].s = t[0].l = t[0].r = t[0].p = 0; root = NewNode(-INF, 0); t[root].r = NewNode(-INF, root); Upd_Up( root ); t[t[root].r].l = Build(0, n-1, t[root].r); Upd_Up(t[root].r); Upd_Up(root); } int main() { //const char path[] = "D:\\Project\\AlgorithmExam\\test.txt"; //freopen(path, "r+", stdin); int n,m; while ( scanf("%d%d", &n, &m) != EOF ){ Init(n); int K,L,R,V; for ( int i = 0; i < m; ++i ){ scanf("%d%d%d", &K, &L, &R); if ( 1 == K ){ scanf("%d", &V); Modify(L, R, V); } else if ( 2 == K ){ Reverse(L, R); } else { printf("%d\n", GetMax(L,R)); } } } return 0; }