[poj][3580][SuperMemo]

题目:http://poj.org/problem?id=3580

View Code
#include <iostream>

#include <cstdio>

#include <cstring>



using namespace std;



const int M = 300000+10;

const int inf = 0x3f3f3f3f;

#define type int



struct node

{

    int size, rev;

    type key, minv, delta;

    node *ch[2], *pre;

    void add(type v)

    {

        if (size == 0)return;

        delta += v, minv += v, key += v;

    }

    void reverse()

    {

        if (size == 0)return;

        rev ^= 1;

        swap(ch[0], ch[1]);

    }

    void update()

    {

        size = ch[0]->size + ch[1]->size + 1;

        minv = min(key, min(ch[0]->minv, ch[1]->minv));

    }

    void pushdown()

    {

        if (delta)

        {

            ch[0]->add(delta);

            ch[1]->add(delta);

        }

        if (rev)

        {

            ch[0]->reverse();

            ch[1]->reverse();

        }

        delta = rev = 0;

    }

};



type arr[M];

node * hash[M];



#define keytree root->ch[1]->ch[0]



class Splay

{

    int cnt, top;

    node *stk[M], data[M];

public:

    node *newnode(type var)

    {

        node *p;

        if (top) p = stk[top--];

        else p = &data[cnt++];

        p->key = p->minv = var;

        p->size = 1;

        p->delta = p->rev = 0;

        p->ch[0] = p->ch[1] = p->pre = null;

        return p;

    }

    void init()

    {

        top = cnt = 0;

        null = newnode(inf);

        null->size = 0;

        root = newnode(inf);

        root->ch[1] = newnode(inf);

        root->ch[1]->pre = root;

        root->update();

    }

    void maketree(int l, int r)

    {

        init();

        keytree = build(l, r);

        keytree->pre = root->ch[1];

        splay(keytree, null);

    }

    node *build(int l, int r)

    {

        if (l > r) return null;

        int mid = (l + r) >> 1;

        node *p = newnode(arr[mid]);

        hash[arr[mid]] = p;

        p->ch[0] = build(l, mid-1);

        p->ch[1] = build(mid+1, r);

        if (p->ch[0] != null)

            p->ch[0]->pre = p;

        if (p->ch[1] != null)

            p->ch[1]->pre = p;

        p->update();

        return p;

    }

    void rotate(node *x, int c)

    {

        node *y = x->pre;

        y->pushdown();

        x->pushdown();

        y->ch[!c] = x->ch[c];

        if (x->ch[c] != null)

            x->ch[c]->pre = y;

        x->pre = y->pre;

        if (y->pre != null)

            y->pre->ch[ y==y->pre->ch[1] ] = x;

        x->ch[c] = y;

        y->pre = x;

        y->update();

        if (y == root) root = x;

    }

    void splay(node *x, node *f)

    {

        x->pushdown();

        while (x->pre != f)

        {

            if (x->pre->pre == f)

            {

                rotate(x, x->pre->ch[0] == x);

                break;

            }

            node *y = x->pre;

            node *z = y->pre;

            int c = (y == z->ch[0]);

            if (x == y->ch[c])

            {

                rotate(x, !c);

                rotate(x, c);

            }

            else

            {

                rotate(y, c);

                rotate(x, c);

            }

        }

        x->update();

    }

    void select(int kth, node *x)

    {

        node * cur = root;

        while (true)

        {

            cur->pushdown();

            int tmp = cur->ch[0]->size;

            if (tmp == kth) break;

            else if (tmp < kth)

                kth -= tmp + 1, cur = cur->ch[1];

            else cur = cur -> ch[0];

        }

        splay(cur, x);

    }

    void insert(int x, type y)

    {

        select(x, null);

        select(x+1, root);

        keytree = newnode(y);

        keytree->pre = root->ch[1];

        root->ch[1]->update();

        splay(keytree, null);

    }

    void insert(int x, int l, int r)

    {

        select(x, null);

        select(x+1, null);

        keytree = build(l, r);

        keytree->pre = root->ch[1];

        root->ch[1]->update();

        splay(keytree, null);

    }

    void erase(node *x)

    {

        if (x == null)return ;

        erase(x->ch[0]);

        erase(x->ch[1]);

        stk[++top] = x;

    }

    void dele(int x, int y)

    {

        select(x-1, null);

        select(y+1, root);

        erase(keytree);

        keytree = null;

        root->ch[1]->update();

        root->update();

    }

    void dele(int x)

    {

        select(x, null);

        deleroot();

    }

    void dele(node * t)

    {

        splay(t, null);

        deleroot();

    }

    void deleroot()

    {

        node *oldroot = root;

        root = root->ch[1];

        root->pre = null;

        select(0, null);

        root->ch[0] = oldroot->ch[0];

        root->ch[0]->pre = root;

        root->update();

        stk[++top] = oldroot;

    }

    void add(int x, int y, type d)

    {

        select(x-1, null);

        select(y+1, root);

        keytree->add(d);

        splay(keytree, null);

    }

    void reverse(int x, int y)

    {

        select(x-1, null);

        select(y+1, root);

        keytree->reverse();

    }

    void revolve(int x, int y, int d)

    {

        int len = y-x+1;

        d = (d % len + len) % len;

        if (d == 0) return ;

        if (d == 1)

        {

            dele(y);

            insert(x-1, stk[top]->key);

        }

        else

        {

            select(y-d+1, null);

            select(y+1, root);

            select(x-1, root);

            select(y, root->ch[1]);

            node *p = root->ch[0]->ch[1];

            root->ch[0]->ch[1] = null;

            root->ch[0]->update();

            root->ch[1]->ch[0]->ch[1] = p;

            p->pre = root->ch[1]->ch[0];

            splay(p, null);

        }

    }

    type getMin(int x, int y)

    {

        select(x-1, null);

        select(y+1, root);

        return keytree->minv;

    }

    int query(type i)

    {

        splay(hash[i], null);

        int ans = root->ch[0]->size;

        return ans;

    }

    void debug()

    {

        vis(root);

    }

    void vis(node* t)

    {

        if (t == null) return;

        vis(t->ch[0]);

        printf("node%2d:lson %2d,rson %2d,pre %2d,sz=%2d,key=%2d\n",

               t - data, t->ch[0] - data, t->ch[1] - data,

               t->pre - data, t->size, t->key);

        vis(t->ch[1]);

    }

    node *root, *null;

} spt;



int main()

{

    freopen("D:/a.txt", "r", stdin);

    int n, m, x, y, z;

    char op[20];

    while (~scanf("%d", &n))

    {

        for (int i=1; i<=n; i++)

            scanf("%d", &arr[i]);

        spt.init();

        if (n > 0)

        {

            node *troot = spt.build(1, n);

            spt.keytree = troot;

            troot->pre = spt.root->ch[1];

            spt.splay(troot, spt.null);

        }

        scanf("%d", &m);

        for (int i=1; i<=m; i++)

        {

            scanf("%s", op);

            if (!strcmp(op, "ADD"))

            {

                scanf("%d%d%d", &x, &y, &z);

                spt.add(x, y, z);

            }

            else if (!strcmp(op, "REVERSE"))

            {

                scanf("%d%d", &x, &y);

                spt.reverse(x, y);

            }

            else if (!strcmp(op, "REVOLVE"))

            {

                scanf("%d%d%d", &x, &y, &z);

                spt.revolve(x, y, z);

            }

            else if (!strcmp(op, "INSERT"))

            {

                scanf("%d%d", &x, &y);

                spt.insert(x, y);

            }

            else if (!strcmp(op, "DELETE"))

            {

                scanf("%d", &x);

                spt.dele(x);

            }

            else {

                scanf("%d%d", &x, &y);

                printf("%d\n", spt.getMin(x, y));

            }

        }

    }

    return 0;

}

你可能感兴趣的:(super)