• hdu 4453 splay


    Looploop

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1651    Accepted Submission(s): 517

    Problem Description
    XXX gets a new toy named Looploop. The toy has N elements arranged in a loop, an arrow pointing to one of the elements, and two preset parameters k1 and k2. Every element has a number on it.



    The figure above shows a Looploop of 6 elments. Let's assuming the preset parameter k1 is 3, and k2 is 4.
    XXX can do six operations with the toy. 

    1: add x 
    Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.



    2: reverse
    Starting from the arrow pointed element, reverse the first k1 clockwise elements.



    3: insert x 
    Insert a new element with number x to the right (along clockwise) of the arrow pointed element.



    4: delete 
    Delete the element the arrow pointed and then move the arrow to the right element.



    5: move x 
    x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.



    6: query
    Output the number on the arrow pointed element in one line.



    XXX wants to give answers to every query in a serial of operations.
     
    Input
    There are multiple test cases.
    For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤105, M≤105) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy. 
    Second line contains N integers ai(-104≤ai≤104) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning. 
    Then m lines follow, each line contains one of the six operations described above.
    It is guaranteed that the "x" in the "add","insert" and "move" operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations. 
    The input ends with a line of 0 0 0 0.
     
    Output
    For each test case, output case number in the first line(formatted as the sample output). Then for each query in the case, output the number on the arrow pointed element in a single line.
     
    Sample Input
    5 1 2 4 3 4 5 6 7 query 5 13 2 4 1 2 3 4 5 move 2 query insert 8 reverse query add 2 query move 1 query move 1 query delete query 0 0 0 0
     
    Sample Output
    Case #1: 3 Case #2: 2 8 10 1 5 1
    /*
    hdu 4453 splay
    把环换成链然后进行splay即可
    主要是move那个操作开始想复杂了,只需要直接进行删除插入
    add、reverse、insert、delete、query
    move 1:把第n+1个点删除,然后放入第一个点之后。
    move 2:把第2个点删除,然后放入第n+1个点后。
    hhh-2016-02-21 07:01:08
    */
    
    #include <functional>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    typedef long  double ld;
    #define key_value ch[ch[root][1]][0]
    const int maxn = 200010;
    
    int ch[maxn][2];
    int pre[maxn],siz[maxn],num[maxn];
    int rev[maxn],key[maxn];
    int add[maxn];
    int Min[maxn],a[maxn];
    int tot,tp;
    int root,n;
    void push_up(int r)
    {
        int lson = ch[r][0],rson = ch[r][1];
        siz[r] = siz[lson] + siz[rson] + 1;
        Min[r] = min(key[r],min(Min[lson],Min[rson]));
    }
    
    void update_add(int r,int val)
    {
        if(!r) return;
        key[r] += val;
        add[r] += val;
        Min[r] += val;
    }
    
    void inOrder(int r)
    {
        if(!r)
            return;
        inOrder(ch[r][0]);
        printf("%d ",key[r]);
        inOrder(ch[r][1]);
    }
    
    void debug()
    {
        inOrder(root);
        cout <<endl;
    }
    
    void update_rev(int r)
    {
        if(!r)return ;
        swap(ch[r][0],ch[r][1]);
        rev[r] ^= 1;
    }
    
    void push_down(int r)
    {
        if(rev[r])
        {
            update_rev(ch[r][0]);
            update_rev(ch[r][1]);
            rev[r] = 0;
        }
        if(add[r])
        {
            update_add(ch[r][0],add[r]);
            update_add(ch[r][1],add[r]);
            add[r] = 0;
        }
    }
    
    
    void NewNode(int &r,int far,int k)
    {
        r = ++tot;
        pre[r] = far;
        ch[r][0] = ch[r][1] = 0;
        siz[r] = 1;
        Min[r] = k;
        key[r] = k;
        rev[r] = 0;
        add[r] = 0;
    }
    
    
    void rotat(int x,int kind)
    {
        int y = pre[x];
        push_down(y);
        push_down(x);
        ch[y][!kind] = ch[x][kind];
        pre[ch[x][kind]] = y;
        if(pre[y])
            ch[pre[y]][ch[pre[y]][1]==y] = x;
        pre[x] = pre[y];
        ch[x][kind] = y;
        pre[y] = x;
        push_up(y);
    }
    
    void build(int &x,int l,int r,int far)
    {
        if(l > r) return ;
        int mid = (l+r) >>1;
        NewNode(x,far,a[mid]);
        build(ch[x][0],l,mid-1,x);
        build(ch[x][1],mid+1,r,x);
        push_up(x);
    }
    
    void splay(int r,int goal)
    {
        push_down(r);
        while(pre[r] != goal)
        {
            if(pre[pre[r]] == goal)
            {
                push_down(pre[r]);
                push_down(r);
                rotat(r,ch[pre[r]][0] == r);
            }
            else
            {
                push_down(pre[pre[r]]);
                push_down(pre[r]);
                push_down(r);
                int y = pre[r];
                int kind = ch[pre[y]][0] == y;
                if(ch[y][kind] == r)
                {
                    rotat(r,!kind);
                    rotat(r,kind);
                }
                else
                {
                    rotat(y,kind);
                    rotat(r,kind);
                }
            }
        }
        push_up(r);
        if(goal == 0)
            root = r;
    }
    
    
    int get_kth(int r,int k)
    {
        push_down(r);
        int t = siz[ch[r][0]] + 1;
        if(k == t)return r;
        if(t > k) return get_kth(ch[r][0],k);
        else return get_kth(ch[r][1],k-t);
    }
    
    int get_next(int r)
    {
        push_down(r);
        if(ch[r][1] == 0)return -1;
        r = ch[r][1];
        while(ch[r][0])
        {
            r = ch[r][0];
            push_down(r);
        }
        return r;
    }
    
    void Reverse(int l,int r)
    {
        splay(get_kth(root,l),0);
        splay(get_kth(root,r+2),root);
        update_rev(key_value);
        push_up(ch[root][1]);
        push_up(root);
    }
    
    void Add(int l,int r,int val)
    {
        splay(get_kth(root,l),0);
        splay(get_kth(root,r+2),root);
        update_add(key_value,val);
        push_up(ch[root][1]);
        push_up(root);
    }
    
    void ini(int n)
    {
        tot = root = 0;
        ch[root][0] = ch[root][1] = pre[root] = siz[root] = num[root] = 0;
        Min[root] = 0x3f3f3f3f;
        rev[root] = add[root] = 0;
        NewNode(root,0,-1);
        NewNode(ch[root][1],root,-1);
        for(int i=1; i <= n; i++)
        {
            scanf("%d",&a[i]);
        }
        build(key_value,1,n,ch[root][1]);
    
        push_up(ch[root][1]);
        push_up(root);
    }
    
    int get_min(int r)
    {
        push_down(r);
        while(ch[r][0])
        {
            r = ch[r][0];
            push_down(r);
        }
        return r;
    }
    
    int Delete(int r)
    {
        int t = get_kth(root,r+1);
        splay(t,0);
        if(ch[root][0] == 0 || ch[root][1] == 0)
        {
            root = ch[root][0] + ch[root][1];
            pre[root] = 0;
            return key[t];
        }
        int k = get_min(ch[root][1]);
        splay(k,root);
        ch[ch[root][1]][0] = ch[root][0];
        root = ch[root][1];
        pre[ch[root][0]] = root;
        pre[root] = 0;
        push_up(root);
        n--;
        return key[t];
    }
    
    void Insert(int x,int y)
    {
        splay(get_kth(root,x),0);
        splay(get_kth(root,x+1),root);
        NewNode(key_value,ch[root][1],y);
        push_up(ch[root][1]);
        push_up(root);
        n++;
    }
    
    void Move(int x)
    {
       if(x == 1)
       {
           int t = Delete(n);
           Insert(1,t);
    //       debug();
       }
       else
       {
           int t = Delete(1);
           Insert(n+1,t);
       }
    }
    
    
    int main()
    {
        int p,k1,k2;
        int cas = 1;
        while(scanf("%d%d%d%d",&n,&p,&k1,&k2) != EOF)
        {
            if(!n && !p && !k1 && !k2)
                break;
            printf("Case #%d:
    ",cas++);
            ini(n);
            char opr[10];
            int x;
            for(int i =1; i <= p; i++)
            {
                scanf("%s",opr);
                if(opr[0] == 'a')
                {
                    scanf("%d",&x);
                    Add(1,k2,x);
                }
                else if(opr[0] == 'm')
                {
                    scanf("%d",&x);
                    Move(x);
                }
                else if(opr[0] == 'r')
                {
                    Reverse(1,k1);
                }
                else if(opr[0] == 'q')
                {
                    printf("%d
    ",key[get_kth(root,2)]);
                }
                else if(opr[0] == 'i')
                {
                    scanf("%d",&x);
                    Insert(2,x);
                }
                else if(opr[0] == 'd')
                {
                    Delete(1);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    mysql误删表,无备份
    感情启示录
    奸的好人之财色战场
    Word神器使用
    Maven工程的Web调试
    IntelIoT技术笔记Java/Eclipse
    IntelIoT技术笔记Maven
    Linux脚本(二)
    MINA
    360是神器
  • 原文地址:https://www.cnblogs.com/Przz/p/5409621.html
Copyright © 2020-2023  润新知