zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    迪杰斯特拉算法简单分析
    华科机考:二叉排序树(改)
    华科机考:八进制
    华科机考:阶乘
    华科机考:找位置
    华科机考:回文字符串
    华科机考:a+b
    华科机考:N阶楼梯上楼
    华科机考:大整数排序
    iOS 适配iOS9
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2588604.html
Copyright © 2011-2022 走看看