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

2010 ACM-ICPC Multi-University Training Contest(1)——Host by FZU

还算是比较简单吧,唯一就是注意离散化,将需要的点建一个点,然后将那些不需要的点以区间的形式记录下来。

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\n",tree[tree[idx].son[0]].size + 1);
        }
        if(quer[x].ty == 2) printf("%d\n",query(quer[x].num));
    }
}

int main()
{
    scanf("%d",&t);
    for(int x = 1; x <= t; ++x)
    {
        printf("Case %d:\n",x);
        cnt = 0; root = 0;
        memset(tree,0,sizeof(tree));
        Init();
        Solve();
    }
    return 0;
}
时间: 2024-10-25 14:47:59

hdu 3454 Queue-jumpers的相关文章

hdu 4441 Queue Sequence(splay)

题目链接:hdu 4441 Queue Sequence 这题看了题解写的,题解传送门 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 #define ls l,m,rt<<1 4 #define rs m+1,r,rt<<1|1 5 using namespace std; 6 typedef long long ll; 7 8 const int N=1e6+7; 9 i

HDU 5493 Queue 树状数组

Queue Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5493 Description N people numbered from 1 to N are waiting in a bank for service. They all stand in a queue, but the queue never moves. It is lunch time now,

【线段树】HDU 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意: N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数,求按身高字典序最小同时满足排名的身高排列. 题目思路: [线段树] 首先可以知道,一个人前面或后面有r个人比他高,那么他是第r+1高或第n-i-r+1高,i为这个人是第几高的. 所以先将人按照身高从小到大排序,接下来,把当前这个人放在第k=min(r+1,n-i-r+1)高的位置. 用线段树维护包

HDU 5493 Queue

Queue Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 68    Accepted Submission(s): 40 Problem DescriptionN people numbered from 1 to N are waiting in a bank for service. They all stand in a que

HDU 4441 Queue Sequence(splay)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并将-i插入某个位置使得满足先进先出(i表示进,-i表示出),这个位置尽量靠右:(2)删除:删掉数字i以及-i:(3)询问:查询i和-i之间的数字的和. 思路:对于没在数列中的数字可以用一个set直接维护.i的插入是正常的splay操作.对于-i的插入,我们首先找到i之前有几个正数,比如有x个,那么-

hdu 5493 Queue treap实现将元素快速插入到第i个位置

input T 1<=T<=1000 n 1<=n<=100000 h1 k1 h2 k2 ... ... hn kn 1<=hi<=1e9  0<=ki<=n-1 sum(n)<=1e6 hi!=hj(i!=j) output hi指第i个人的身高,ki指这个人前面或者后面比他高的人数 Case #cas: 输出可能的最小序列,没有输出impossible 做法:将所有人按身高排序,从高到低插入数组中,则插入到第i个人时,数组里所有人都比他高,用tr

补题列表

上海网络赛: HDU 5468 Puzzled Elena HDU 5469 Antonidas HDU 5473 There was a kingdom 合肥网络赛: HDU 5487 Difference of Languages HDU 5486 Difference of Clustering HDU 5489 Removed Interval HDU 5492 Find a path HDU 5493 Queue 弱校联萌Day1: B. Carries D. Vertex Cover

HDU 1908 Double Queue&lt;Set&gt;

Problem Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of th

hdu 1972.Printer Queue 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1972 题目意思:需要模拟打印机打印.打印机里面有一些 job,每个job被赋予1-9的其中一个值,越大表示优先级越高,越早被打印.job这个队列是会向前推进的,如果排在最前面的job优先级最高,那么才打印,否则就把这个job放到队列最后.问给出 m 这个位置的job要经过多长时间才被打印. 规定每次打印时间为一分钟,移动 job到队列最后不占时间. 练开优先队列就继续吧---不过这题不是咯. 仅仅用