HNOI2002 营业额统计
/*******************************\
* @prob: HNOI2002 营业额统计 *
* @auth: Wang Junji *
* @stat: Accepted. *
* @date: June. 28th, 2012 *
* @memo: 伸展树 *
\*******************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
const int maxN = 200010, INF = 0x3f3f3f3f;
class SplayTree
{
private:
struct Node
{
int key, cnt, sz; Node *F, *lc, *rc; Node() {} /* Node */
Node(int key): key(key), cnt(1), sz(1) {} /* Node */
} NIL[maxN], *T, *tot;
Node* NewNode(int key)
{
Node* tmp = new (tot++) Node(key);
tmp -> F = tmp -> lc = tmp -> rc = NIL;
return tmp;
} /* NewNode */
void update(Node* T) {T -> sz = T -> lc -> sz + T -> rc -> sz + T -> cnt; return;} /* update */
void Zig(Node* T)
{
Node *P = T -> F, *tmp = T -> rc;
if (P == this -> T) this -> T = T;
else (P -> F -> lc == P) ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> lc = tmp;
tmp -> F = T -> rc = P; update(P); return;
} /* Zig */
void Zag(Node* T)
{
Node *P = T -> F, *tmp = T -> lc;
if (P == this -> T) this -> T = T;
else (P -> F -> lc == P) ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> rc = tmp;
tmp -> F = T -> lc = P; update(P); return;
} /* Zag */
void Splay(Node*& T, Node* t)
{
while (t != T)
{
Node* P = t -> F;
if (P == T) P -> lc == t ? Zig(t) : Zag(t);
else
{
if (P -> F -> lc == P) P -> lc == t ? Zig(P) : Zag(t), Zig(t);
else P -> lc == t ? Zig(t) : Zag(P), Zag(t);
} /* else */
} /* while */
update(t); return;
} /* Splay */
void Find(int v)
{
for (Node* t = T; t != NIL;)
{
if (v == t -> key ||
(v < t -> key && t -> lc == NIL) ||
(v > t -> key && t -> rc == NIL))
{Splay(T, t); break;} /* if */
t = v < t -> key ? t -> lc : t -> rc;
} /* for */
return;
} /* Find */
public:
SplayTree()
{
tot = NIL; NewNode(0); NewNode(~INF); NewNode(INF);
NIL -> sz = NIL -> cnt = 0;
NIL[1].rc = NIL + 2, NIL[1].sz = 2;
NIL[2].F = NIL + 1; T = NIL + 1;
} /* SplayTree */
void Ins(int v)
{
Node *t = T;
while (t != NIL)
{
++t -> sz;
if (v == t -> key) {++t -> cnt; break;}
if (v < t -> key && t -> lc == NIL)
{
Node* p = NewNode(v);
t -> lc = p, p -> F = t;
t = p; break;
} /* if */
if (v > t -> key && t -> rc == NIL)
{
Node* p = NewNode(v);
t -> rc = p, p -> F = t;
t = p; break;
} /* if */
t = v < t -> key ? t -> lc : t -> rc;
} /* while */
if (t != NIL) Splay(T, t);
return;
} /* Ins */
int pred(int v)
{
Find(v); if (T -> cnt > 1) return v;
Node* t = T -> lc;
for (; t -> rc != NIL; t = t -> rc);
return t -> key;
} /* pred */
int succ(int v)
{
Find(v); if (T -> cnt > 1) return v;
Node* t = T -> rc;
for (; t -> lc != NIL; t = t -> lc);
return t -> key;
} /* succ */
} Tr; int n, x;
int main()
{
freopen("Revenue.in" , "r", stdin );
freopen("Revenue.out", "w", stdout);
scanf("%d%d", &n, &x); Tr.Ins(x); int ans = x;
while (--n)
{
x = 0; scanf("%d", &x); Tr.Ins(x);
//输入数据中漏了两个数,所以读入前x要赋为0。
int pred = Tr.pred(x), succ = Tr.succ(x);
ans += std::min(x - pred, succ - x);
} /* while */
printf("%d\n", ans); return 0;
} /* main */
/*
伸展树模板题,不多说。
*/
hdu1890 Robotic Sort
/********************************\
* @prob: hdu1890 Robotic Sort *
* @auth: Wang Junji *
* @stat: Accepted. *
* @date: June. 30th, 2012 *
* @memo: 伸展树 *
\********************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
const int maxN = 100010;
class SplayTree
{
private:
struct Node
{
int key, sz; bool rev; Node *lc, *rc, *F; Node() {} /* Node */
Node(int key): key(key), sz(1), rev(false) {} /* Node */
} NIL[maxN], *ele[maxN], *T, *tot; int cur;
Node* NewNode(int key)
{
Node* T = new (tot++) Node(key);
T -> lc = T -> rc = T -> F = NIL;
return T;
} /* NewNode */
void pushdown(Node* T)
{
if (T -> rev)
{
std::swap(T -> lc, T -> rc);
if (T -> lc != NIL) T -> lc -> rev ^= 1;
if (T -> rc != NIL) T -> rc -> rev ^= 1;
T -> rev = false;
} /* if */
return;
} /* pushdown */
void update(Node* T) {T -> sz = T -> lc -> sz + T -> rc -> sz + 1;} /* update */
void Zig(Node* T)
{
Node *P = T -> F, *tmp = T -> rc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> rc);
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> lc = tmp;
tmp -> F = T -> rc = P; update(P); return;
} /* Zig */
void Zag(Node* T)
{
Node *P = T -> F, *tmp = T -> lc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> lc);
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> rc = tmp;
tmp -> F = T -> lc = P; update(P); return;
} /* Zag */
void Splay(Node*& T, Node* t)
{
for (pushdown(t); t != T;)
{
Node* P = t -> F;
if (P == T) P -> lc == t ? Zig(t) : Zag(t);
else
{
if (P -> F -> lc == P) P -> lc == t ? Zig(P) : Zag(t), Zig(t);
else P -> lc == t ? Zig(t) : Zag(P), Zag(t);
} /* else */
} /* for */
update(t); return;
} /* Splay */
void K_th(Node*& T, int k)
{
for (Node* t = T; pushdown(t), t != NIL && k > 0;)
{
if (k == t -> lc -> sz + 1) {Splay(T, t); return;}
if (k <= t -> lc -> sz) t = t -> lc;
else k -= t -> lc -> sz + 1, t = t -> rc;
} /* for */
return;
} /* K_th */
void modify(Node* t)
{
if (t -> F != NIL) modify(t -> F);
pushdown(t);
return;
} /* modify */
static bool cmp(const Node* const& a, const Node* const& b) {return a -> key < b -> key;} /* cmp */
public:
SplayTree() {init();} /* SplayTree */
void init(const int* __fir = NULL, const int *__la = NULL)
{
tot = NIL; T = NewNode(0); NIL[0].sz = 0; cur = 0;
if (__fir == __la) return;
const int* fir = __fir; Node *p, *q;
ele[0] = T = p = NewNode(*fir);
while (++fir != __la)
{
ele[fir - __fir] = q = NewNode(*fir);
p -> rc = q, q -> F = p, p = q;
} /* while */
std::stable_sort(ele, ele + (__la - __fir), cmp);
//这里一定要用stable_sort,否则会打乱相同大小元素的顺序。
Splay(T, p); return;
} /* init */
int count()
{
Node* t = ele[cur++];
modify(t); Splay(T, t);
int res = T -> lc -> sz;
if (T -> lc == NIL) T = T -> rc, T -> F = NIL;
else
{
T -> lc -> rev ^= 1;
K_th(T -> lc, T -> lc -> sz);
T -> lc -> rc = T -> rc;
T -> rc -> F = T -> lc;
T = T -> lc;
T -> F = NIL;
update(T);
} /* else */
return res;
} /* count */
} Tr; int a[maxN], n;
int main()
{
freopen("Sort.in" , "r", stdin );
freopen("Sort.out", "w", stdout);
while (~scanf("%d", &n) && n)
{
for (int* i = a; i != a + n;) scanf("%d", i++);
if (n == 1) {printf("1\n"); continue;}
Tr.init(a, a + n);
for (int i = 0; i + 1 < n; ++i)
printf("%d ", i + Tr.count() + 1);
printf("%d\n", n + Tr.count());
} /* while */
return 0;
} /* main */
/*
由于每次翻转都必然有一个元素(未排好序元素中的最小)达到指定位置,题目意思也就是求每次翻转的终点。
将还需排序的结点放在一颗伸展树中,
每次将里面最小的元素提到根,然后倒转左子树,删掉根(根结点已经排好序,所以删掉根,同时由于对根结点的排序,根结点左边的所有数都会被翻转一次),于是翻转的终点就是已经排好序的元素个数加上左子树的大小再加一。
*/
hdu3487 Play with Chain
/***********************************\
* @prob: hdu3487 Play with Chain *
* @auth: Wang Junji *
* @stat: Accepted. *
* @date: June. 29th, 2012 *
* @memo: 伸展树 *
\***********************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
const int maxN = 3000010;
class SplayTree
{
private:
struct Node
{
int key, sz; bool rev; Node *lc, *rc, *F; Node() {} /* Node */
Node(int key): key(key), sz(1), rev(false) {} /* Node */
} NIL[maxN], *T, *tot;
static int num[maxN], *fir, *la;
Node* NewNode(int v)
{
Node* T = new (tot++) Node(v);
T -> lc = T -> rc = T -> F = NIL;
return T;
} /* NewNode */
void update(Node* T) {T -> sz = T -> lc -> sz + T -> rc -> sz + 1; return;} /* update */
void pushdown(Node* T)
{
if (T -> rev)
{
std::swap(T -> lc, T -> rc);
if (T -> lc != NIL) T -> lc -> rev ^= 1;
if (T -> rc != NIL) T -> rc -> rev ^= 1;
T -> rev = false;
} /* if */
return;
} /* pushdown */
void Zig(Node* T)
{
Node *P = T -> F, *tmp = T -> rc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> rc);
if (P == this -> T) this -> T = T;
else (P -> F -> lc == P) ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> lc = tmp;
tmp -> F = T -> rc = P; update(P); return;
} /* Zig */
void Zag(Node* T)
{
Node *P = T -> F, *tmp = T -> lc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> lc);
if (P == this -> T) this -> T = T;
else (P -> F -> lc == P) ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> rc = tmp;
tmp -> F = T -> lc = P; update(P); return;
} /* Zag */
void Splay(Node*& T, Node* t)
{
for (pushdown(t); t != T;)
{
Node* P = t -> F;
if (P == T) (P -> lc == t) ? Zig(t) : Zag(t);
else
{
if (P -> F -> lc == P) (P -> lc == t) ? Zig(P) : Zag(t), Zig(t);
else (P -> lc == t) ? Zig(t) : Zag(P), Zag(t);
} /* else */
} /* for */
update(t); return;
} /* Splay */
void K_th(Node*& T, int k)
{
for (Node* t = T; t != NIL && k > 0;)
{
pushdown(t);
if (k == t -> lc -> sz + 1) {Splay(T, t); return;}
if (k <= t -> lc -> sz) t = t -> lc;
else k -= t -> lc -> sz + 1, t = t -> rc;
} /* for */
return;
} /* K_th */
void print(Node* T)
{
if (T == NIL) return; pushdown(T);
if (T -> lc != NIL) print(T -> lc);
if (T -> key) *la++ = T -> key;
if (T -> rc != NIL) print(T -> rc);
return;
} /* print */
public:
SplayTree() {init();} /* SplayTree */
void init(int fir = 0, int la = 0)
{
tot = NIL; NewNode(0); NewNode(0); NewNode(0);
NIL[0].sz = 0;
NIL[1].sz = 2; NIL[1].rc = NIL + 2;
NIL[2].F = NIL + 1;
T = NIL + 1;
if (fir == la) return;
Node* p = NewNode(fir++);
T -> rc -> lc = p; p -> F = T -> rc;
while (fir != la)
{
Node* q = NewNode(fir++);
p -> rc = q; q -> F = p; p = q;
} /* while */
Splay(T, p); return;
} /* init */
void cut(int L, int R, int pos)
{
K_th(T, L); K_th(T -> rc, R - L + 2);
Node* p = T -> rc -> lc;
T -> rc -> lc = p -> F = NIL;
update(T -> rc); update(T);
K_th(T, pos + 1); K_th(T -> rc, 1);
T -> rc -> lc = p, p -> F = T -> rc;
update(T -> rc); update(T); return;
} /* cut */
void Flip(int L, int R)
{
K_th(T, L); K_th(T -> rc, R - L + 2);
T -> rc -> lc -> rev ^= 1;
Splay(T, T -> rc -> lc); return;
} /* Flip */
void println()
{
fir = la = num; print(T);
if (fir == la) {puts(""); return;} /* if */
while (fir != la - 1) printf("%d ", *fir++);
printf("%d\n", *fir++); return;
} /* println */
} Tr; int n, m, x, y, p; char str[20];
int SplayTree::num[maxN], *SplayTree::fir, *SplayTree::la;
int main()
{
freopen("Chain.in" , "r", stdin );
freopen("Chain.out", "w", stdout);
while (~scanf("%d%d", &n, &m) && ~n && ~m)
{
Tr.init(1, n + 1);
while (m--) switch (scanf("%s%d%d", str, &x, &y), str[0])
{
case 'C': scanf("%d", &p); Tr.cut(x, y, p); break;
case 'F': Tr.Flip(x, y); break;
} /* switch */
Tr.println();
} /* while */
return 0;
} /* main */
/*
伸展树的模板题,不再多说。
注意输出时在行末不能多一个空格。
*/
spoj4487 Can you answer these queries VI
/****************************************************\
* @prob: spoj4487 Can you answer these queries VI *
* @auth: Wang Junji * @stat: Accepted. *
* @date: June. 29th, 2012 * @memo: 伸展树 *
\****************************************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
using std::min; using std::max;
const int maxN = 200010, INF = 0x07070707;
inline int& gmax(int& a, const int& b) {return a > b ? a : (a = b);} /* gmax */
inline int& gmin(int& a, const int& b) {return a < b ? a : (a = b);} /* gmin */
class SplayTree
{
private:
struct Node
{
int key, sum, mls, mrs, Max, sz; Node *lc, *rc, *F; Node() {} /* Node */
Node(int key): key(key), sum(key), mls(key), mrs(key), Max(key), sz(1) {} /* Node */
} NIL[maxN], *T, *tot;
Node* NewNode(int key)
{
Node* T = new (tot++) Node(key);
T -> lc = T -> rc = T -> F = NIL;
return T;
} /* NewNode */
void update(Node* T)
{
T -> sum = T -> lc -> sum + T -> rc -> sum + T -> key;
T -> sz = T -> lc -> sz + T -> rc -> sz + 1;
T -> mls = T -> lc -> mls;
gmax(T -> mls, T -> lc -> sum + T -> key);
gmax(T -> mls, T -> lc -> sum + T -> key + T -> rc -> mls);
T -> mrs = T -> rc -> mrs;
gmax(T -> mrs, T -> rc -> sum + T -> key);
gmax(T -> mrs, T -> rc -> sum + T -> key + T -> lc -> mrs);
T -> Max = T -> key;
gmax(T -> Max, max(T -> lc -> Max, T -> rc -> Max));
gmax(T -> Max, max(T -> mls, T -> mrs));
gmax(T -> Max, max(T -> lc -> mrs, T -> rc -> mls) + T -> key);
gmax(T -> Max, T -> lc -> mrs + T -> key + T -> rc -> mls);
return;
} /* update */
void Zig(Node* T)
{
Node *P = T -> F, *tmp = T -> rc;
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> lc = tmp;
tmp -> F = T -> rc = P; update(P); return;
} /* Zig */
void Zag(Node* T)
{
Node *P = T -> F, *tmp = T -> lc;
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> rc = tmp;
tmp -> F = T -> lc = P; update(P); return;
} /* Zag */
void Splay(Node*& T, Node* t)
{
while (T != t)
{
Node* P = t -> F;
if (P == T) P -> lc == t ? Zig(t) : Zag(t);
else
{
if (P -> F -> lc == P) P -> lc == t ? Zig(P) : Zag(t), Zig(t);
else P -> lc == t ? Zig(t) : Zag(P), Zag(t);
} /* else */
} /* while */
update(t); return;
} /* Splay */
void K_th(Node*& T, int k)
{
for (Node* t = T; t != NIL && k > 0;)
{
if (k == t -> lc -> sz + 1) {Splay(T, t); return;}
if (k <= t -> lc -> sz) t = t -> lc;
else k -= t -> lc -> sz + 1, t = t -> rc;
} /* for */
return;
} /* K_th */
public:
SplayTree()
{
tot = NIL; NewNode(~INF); NewNode(~INF); NewNode(~INF);
NIL[0].sz = 0; NIL[0].sum = NIL[0].key = 0;
NIL[1].sz = 2; NIL[1].rc = NIL + 2; NIL[1].sum = NIL[1].key = 0;
NIL[2].F = T = NIL + 1; NIL[2].sum = NIL[2].key = 0;
} /* SplayTree */
void Ins(int pos, int v)
{
K_th(T, pos); K_th(T -> rc, 1);
Node* p = NewNode(v);
T -> rc -> lc = p, p -> F = T -> rc;
update(T -> rc); update(T); return;
} /* Ins */
void Del(int pos)
{
K_th(T, pos); K_th(T -> rc, 2);
T -> rc -> lc = NIL;
update(T -> rc); update(T); return;
} /* Del */
void Replace(int pos, int v) {K_th(T, pos + 1); T -> key = v; update(T); return;} /* Replace */
int query(int L, int R)
{
K_th(T, L); K_th(T -> rc, R - L + 2);
return T -> rc -> lc -> Max;
} /* query */
} Tr; int n, m, x, y; char str[10];
int main()
{
freopen("query4.in" , "r", stdin );
freopen("query4.out", "w", stdout);
scanf("%d", &n);
for (int i = 0; i < n; ++i) scanf("%d", &x), Tr.Ins(i + 1, x);
scanf("%d", &m);
while (m--) switch (scanf("%s%d", str, &x), str[0])
{
case 'D': Tr.Del(x); break;
case 'I': scanf("%d", &y); Tr.Ins (x, y); break;
case 'R': scanf("%d", &y); Tr.Replace(x, y); break;
case 'Q': scanf("%d", &y); printf("%d\n", Tr.query(x, y)); break;
} /* switch */
return 0;
} /* main */
/*
伸展树模板题,不再多说。
*/
NOI2005 维护数列
/****************************\
* @prob: NOI2005 维护数列 *
* @auth: Wang Junji *
* @stat: Accepted. *
* @date: June. 29th, 2012 *
* @memo: 伸展树 *
\****************************/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
using std::min; using std::max;
const int maxN = 300010, INF = 0x07070707;
inline int& gmax(int& a, const int& b) {return a > b ? a : (a = b);} /* gmax */
inline int& gmin(int& a, const int& b) {return a < b ? a : (a = b);} /* gmin */
class SplayTree
{
private:
struct Node
{
int key, sum, mls, mrs, Max, sz; bool rev, sm;
Node *lc, *rc, *F; Node() {} /* Node */
Node(int key): key(key), sum(key), mls(key),
mrs(key), Max(key), sz(1), rev(false), sm(false) {} /* Node */
} *NIL, *T;
Node* NewNode(int v)
{
Node* T = new Node(v);
T -> lc = T -> rc = T -> F = NIL;
return T;
} /* NewNode */
void release(Node*& T)
{
if (T -> lc != NIL) release(T -> lc);
if (T -> rc != NIL) release(T -> rc);
if (T != NIL) delete T;
T = NIL; return;
} /* release */
void pushdown(Node* T)
{
Node *&lc = T -> lc, *&rc = T -> rc;
if (T -> rev)
{
std::swap(lc, rc);
std::swap(T -> mls, T -> mrs); //
if (lc != NIL) lc -> rev ^= 1;
if (rc != NIL) rc -> rev ^= 1;
T -> rev = false;
} /* if */
if (T -> sm)
{
if (lc != NIL) lc -> sm = true, lc -> key = T -> key;
if (rc != NIL) rc -> sm = true, rc -> key = T -> key;
T -> sum = T -> sz * T -> key; //
T -> mls = T -> mrs = T -> Max = max(T -> sum, T -> key); //
T -> sm = false;
} /* if */
return;
} /* pushdown */
void update(Node* T)
{
Node *&lc = T -> lc, *&rc = T -> rc;
T -> sz = lc -> sz + rc -> sz + 1;
T -> sum = lc -> sum + rc -> sum + T -> key;
T -> mls = lc -> mls;
gmax(T -> mls, lc -> sum + T -> key);
gmax(T -> mls, lc -> sum + T -> key + rc -> mls);
T -> mrs = rc -> mrs;
gmax(T -> mrs, rc -> sum + T -> key);
gmax(T -> mrs, rc -> sum + T -> key + lc -> mrs);
T -> Max = T -> key;
gmax(T -> Max, max(lc -> Max, rc -> Max));
gmax(T -> Max, max(T -> mls, T -> mrs));
gmax(T -> Max, max(lc -> mrs, rc -> mls) + T -> key);
gmax(T -> Max, lc -> mrs + T -> key + rc -> mls);
return;
} /* update */
void Zig(Node* T)
{
Node *P = T -> F, *tmp = T -> rc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> rc);
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> lc = tmp;
tmp -> F = T -> rc = P; update(P); return;
} /* Zig */
void Zag(Node* T)
{
Node *P = T -> F, *tmp = T -> lc;
pushdown(T -> lc); pushdown(T -> rc); pushdown(P -> lc);
if (P == this -> T) this -> T = T;
else P -> F -> lc == P ? (P -> F -> lc = T) : (P -> F -> rc = T);
T -> F = P -> F; P -> F = T; P -> rc = tmp;
tmp -> F = T -> lc = P; update(P); return;
} /* Zag */
void Splay(Node*& T, Node* t)
{
for (pushdown(t); t != T;)
{
Node* P = t -> F;
if (P == T) P -> lc == t ? Zig(t) : Zag(t);
else
{
if (P -> F -> lc == P) P -> lc == t ? Zig(P) : Zag(t), Zig(t);
else P -> lc == t ? Zig(t) : Zag(P), Zag(t);
} /* else */
} /* for */
update(t); return;
} /* Splay */
void K_th(Node*& T, int k)
{
for (Node* t = T; pushdown(t), t != NIL && k > 0;)
{
if (k == t -> lc -> sz + 1) {Splay(T, t); return;}
if (k <= t -> lc -> sz) t = t -> lc;
else k -= t -> lc -> sz + 1, t = t -> rc;
} /* for */
return;
} /* K_th */
public:
SplayTree()
{
NIL = NewNode(~INF); T = NewNode(~INF); T -> rc = NewNode(~INF);
NIL -> lc = NIL -> rc = NIL -> F = NIL;
NIL -> sz = 0; NIL -> key = NIL -> sum = 0; T -> sz = 2;
T -> rc -> F = T;
} /* SplayTree */
void Ins(int pos, int* fir, int* la)
{
if (fir == la) return;
K_th(T, pos + 1); K_th(T -> rc, 1);
Node* p = NewNode(*fir++);
T -> rc -> lc = p, p -> F = T -> rc;
while (fir != la)
{
Node* q = NewNode(*fir++);
p -> rc = q, q -> F = p, p = q;
} /* while */
Splay(T, p); return;
} /* Ins */
void Del(int pos, int num)
{
K_th(T, pos); K_th(T -> rc, num + 1);
release(T -> rc -> lc); Splay(T, T -> rc);
//update(T -> rc); update(T); return;
} /* Del */
void rev(int pos, int num)
{
K_th(T, pos); K_th(T -> rc, num + 1);
T -> rc -> lc -> rev ^= 1; Splay(T, T -> rc -> lc); //
//pushdown(T -> rc -> lc); return;
} /* rev */
void mksm(int pos, int num, int v)
{
K_th(T, pos); K_th(T -> rc, num + 1);
T -> rc -> lc -> key = v;
T -> rc -> lc -> sm = true; Splay(T, T -> rc -> lc); //
//pushdown(T -> rc -> lc); return;
} /* mksm */
int qsum(int pos, int num)
{
K_th(T, pos); K_th(T -> rc, num + 1);
return T -> rc -> lc -> sum;
} /* qsum */
int qmax() {return T -> Max;} /* qmax */
} Tr; int a[maxN], n, m, x, y, p; char str[20];
int main()
{
freopen("sequence.in" , "r", stdin );
freopen("sequence.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int* i = a; i != a + n;) scanf("%d", i++);
Tr.Ins(0, a, a + n);
while (m--)
{
scanf("%s", str);
if (!strcmp(str, "MAX-SUM")) printf("%d\n", Tr.qmax());
else
{
scanf("%d%d", &x, &y);
if (!strcmp(str, "GET-SUM")) printf("%d\n", Tr.qsum(x, y));
else if (!strcmp(str, "DELETE" )) Tr.Del(x, y);
else if (!strcmp(str, "REVERSE")) Tr.rev(x, y);
else if (!strcmp(str, "INSERT" ))
{
for (int* i = a; i != a + y;) scanf("%d", i++);
Tr.Ins(x, a, a + y);
} /* if */
else scanf("%d", &p), Tr.mksm(x, y, p);
} /* else */
} /* while */
return 0;
} /* main */
/*
要注意两个虚拟结点的sum值不能设为零。
*/