zoukankan      html  css  js  c++  java
  • hdu 3454 Queue-jumpers

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


    Problem Description
    Ponyo and Garfield are waiting outside the box-office for their favorite movie. Because queuing is so boring, that they want to play a game to kill the time. The game is called “Queue-jumpers”. Suppose that there are N people numbered from 1 to N stand in a line initially. Each time you should simulate one of the following operations:
    1.  Top x :Take person x to the front of the queue
    2.  Query x: calculate the current position of person x
    3.  Rank x: calculate the current person at position x
    Where x is in [1, N].
    Ponyo is so clever that she plays the game very well while Garfield has no idea. Garfield is now turning to you for help.
     
    Input
    In the first line there is an integer T, indicates the number of test cases.(T<=50)
    In each case, the first line contains two integers N(1<=N<=10^8), Q(1<=Q<=10^5). Then there are Q lines, each line contain an operation as said above. 
     
    Output
    For each test case, output “Case d:“ at first line where d is the case number counted from one, then for each “Query x” operation ,output the current position of person x at a line, for each “Rank x” operation, output the current person at position x at a line.
     
    Sample Input
    3
    9 5
    Top 1
    Rank 3
    Top 7
    Rank 6
    Rank 8
    6 2
    Top 4
    Top 5
    7 4
    Top 5
    Top 2
    Query 1
    Rank 6
     
    Sample Output
    Case 1:
    3
    5
    8
    Case 2:
    Case 3:
    3
    6
    Author
    wzc1989
    Source
     
    还算是比较简单吧,唯一就是注意离散化,将需要的点建一个点,然后将那些不需要的点以区间的形式记录下来。
    top删除那个点,然后在将他插入在小的位置。
    rank 这个就不说了
    query 将这个点放到根节点,然后在输出左边的节点+1.
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    const int N = 100000 + 11;
    using namespace std;
    int t,n,m,tot,li[N],id[N];
    struct Query
    {
        int ty,num;
    }quer[N];
    int root,cnt;
    struct Splay_tree
    {
        int l,r,cnt,size,f,son[2];
        void news(int L,int R)
        {
            l = L, r = R, cnt = R - L + 1, size = f = son[0] = son[1] = 0;
        }
        void clear()
        {
            l = r = cnt = size = f = son[0] = son[1] = 0;
        }
    } tree[N<<1];
    
    int get(int x)
    {
        return x == tree[tree[x].f].son[1];
    }
    
    void updata(int x)
    {
        tree[x].size = tree[x].cnt;
        if(tree[x].son[0]) tree[x].size += tree[tree[x].son[0]].size;
        if(tree[x].son[1]) tree[x].size += tree[tree[x].son[1]].size;
    }
    
    void rotate(int x)
    {
        int fa = tree[x].f; int gfa = tree[fa].f;
        int ze = get(x);
        tree[fa].son[ze] = tree[x].son[ze^1]; tree[tree[fa].son[ze]].f = fa;
        tree[x].son[ze^1] = fa, tree[fa].f = x;tree[x].f = gfa;
        ze = (fa == tree[gfa].son[1]);
        if(gfa)
            tree[gfa].son[ze] = x;
        updata(fa), updata(x);
    }
    
    
    void splay(int x)
    {
        for(int i; i = tree[x].f;rotate(x))
        {
            if(tree[i].f)
                if(get(x) == get(i)) rotate(i);
        }
        root = x;
    }
    
    
    
    void insert(int l,int r,int idx)
    {
        //cout<<l<<" "<<r<<" "<<endl;
        if(root == 0){tree[idx].news(l,r),root = idx; return;}
        int now = root,fa;
        while(1)
        {
            int ze = l > tree[now].l;
            fa = now; now = tree[fa].son[ze];
            if(!now)
            {
                tree[idx].news(l,r);tree[idx].f = fa;
                tree[fa].son[ze] = idx,updata(idx);
                updata(fa),splay(idx);return;
            }
        }
    }
    
    
    void Init()
    {
        scanf("%d%d",&n,&m);
        char ch[10];
        for(int i = 1; i <= m; ++i)
        {
            scanf("%s%d",ch,&quer[i].num);
            if(ch[0] == 'T') quer[i].ty = 1;
            if(ch[0] == 'R') quer[i].ty = 2;
            if(ch[0] == 'Q') quer[i].ty = 3;
            li[i] = quer[i].num;
        }
        sort(li + 1,li + 1 + m); tot = 1;
        for(int i = 2; i <= m; ++i)
            if(li[i] != li[tot]) li[++tot] = li[i];
        li[tot+1] = n + 1;     cnt = 1;
        if(li[1] != 1) insert(1,li[1]-1,1);    
        for(int i = 1; i <= tot; ++i)
        {
            insert(li[i],li[i],++cnt);
            id[i] = cnt;
            if(li[i] != li[i+1] + 1) insert(li[i] + 1, li[i+1] - 1,++cnt);
        }
    }
    
    int binary_search(int num)
    {
        int l = 1,r = tot;
        while(l <= r)
        {
            int mid = l + ((r-l)>>1);
            if(li[mid] == num) return id[mid];
            if(li[mid] < num) l = mid + 1;
            else r = mid - 1;
        }
        return -1;
    }
    
    int pre(int x)
    {
        x = tree[x].son[0];
        while(tree[x].son[1]) x = tree[x].son[1]; return x;
    }
    
    void del(int x)
    {
        splay(x);
        if(!tree[x].son[0] && !tree[x].son[1]){root = 0, tree[x].clear(); return;}
        if(!tree[x].son[0] || !tree[x].son[1])
        {
            int ze = !tree[x].son[1];
            int root_y = root; root = tree[x].son[ze^1];
            tree[root].f = 0, tree[root_y].clear(); return;
        }
        int pres = pre(root); splay(pres);
        tree[pres].son[1] = tree[x].son[1];
        tree[tree[pres].son[1]].f = pres; 
        tree[x].clear(),updata(pres);
    }
    
    void insert_min(int l,int idx)
    {
        if(root  == 0) {tree[idx].news(l,l),root = idx; return;}
        int now = root;
        while(1)
        {
            int fa = now; now = tree[fa].son[0];
            if(!now)
            {
                tree[idx].news(l,l); tree[fa].son[0] = idx;
                tree[idx].f = fa; updata(idx);
                updata(fa),splay(idx); return;
            }
        }
    }
    
    int query(int ranks)
    {
        int now = root;
        while(1)
        {
            int sum = 0;
        
            if(tree[now].son[0]) sum += tree[tree[now].son[0]].size;
            if(sum >= ranks) {now = tree[now].son[0]; continue;}
            if(sum + tree[now].cnt >= ranks) return tree[now].l + ranks - sum - 1;
             ranks -= (sum + tree[now].cnt),now = tree[now].son[1];
            
        }
    }
    
    
    void Solve()
    {
        for(int x = 1; x <= m; ++x)
        {
            if(quer[x].ty == 1) 
            {
                int idx = binary_search(quer[x].num);
                del(idx);
                insert_min(quer[x].num,idx);
            }
            if(quer[x].ty == 3)
            {
                int idx = binary_search(quer[x].num);
                splay(idx);
                printf("%d
    ",tree[tree[idx].son[0]].size + 1);
            }
            if(quer[x].ty == 2) printf("%d
    ",query(quer[x].num));
        }
    }
    
    int main()
    {
        scanf("%d",&t);
        for(int x = 1; x <= t; ++x)
        {
            printf("Case %d:
    ",x);
            cnt = 0; root = 0;
            memset(tree,0,sizeof(tree));
            Init(); 
            Solve();
        }
        return 0;
    }
  • 相关阅读:
    Python学习笔记009_构造与析构
    Python学习笔记008_类_对象_继承_组合_类相关的BIF
    Python学习笔记007_图形用户界面[EasyGui][Tkinter]
    Python学习笔记006_异常_else_with
    Python学习笔记005_文件_OS_模块_pickle
    Python学习笔记004_字典_集合
    小甲鱼:Python学习笔记003_函数
    小甲鱼:Python学习笔记002_数组_元组_字符串
    Java数据库连接泄漏应对办法-基于Weblogic服务器
    java单点登录
  • 原文地址:https://www.cnblogs.com/Ateisti/p/6385682.html
Copyright © 2011-2022 走看看