【伸展树】伸展树复习

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值不能设为零。

*/



你可能感兴趣的:(【伸展树】伸展树复习)