博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[poj][3580][SuperMemo]

Posted on 2012-07-12 18:48  紫华弦筝  阅读(143)  评论(0编辑  收藏  举报

题目: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;
}