zoukankan      html  css  js  c++  java
  • hdoj 5249 KPI(treap)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5249

    思路分析:使用queue记录管道中的值并使用treap能够查询第K大的功能查询第floor(m/2)+1大的数值;

    对于in value操作,将value插入queue中和treap中;对于out操作,在treap中删除queue中队头元素,并在queue中使队头元素出队;

    对于query操作,因为tail – head的值即为管道中的值的个数,使用treap查询第floor((tail – head) / 2) + 1大的元素即可;

    代码如下:

    #include <cstdio>
    #include <ctime>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const int MAX_N = 10000 + 100;
    int queue[MAX_N];
    
    struct Node{
        Node *ch[2];
        int value, key;
        int size;
        int cmp(int x) const{
            if (x == value) return -1;
            return x < value ? 0 : 1;
        }
        void Maintain(){
            size = 1;
            if (ch[0] != NULL) size += ch[0]->size;
            if (ch[1] != NULL) size += ch[1]->size;
        }
    };
    
    void Rotate(Node *&o, int d){
        Node *k = o->ch[d ^ 1];
        o->ch[d ^ 1] = k->ch[d];
        k->ch[d] = o;
        o->Maintain();
        k->Maintain();
        o = k;
    }
    
    void Insert(Node *&o, int x){
        if (o == NULL){
            o = new Node();
            o->ch[0] = o->ch[1] = NULL;
            o->value = x;
            o->key = rand();
        }
        else{
            int d = (x < (o->value) ? 0 : 1);
            Insert(o->ch[d], x);
            if (o->ch[d]->key > o->key)
                Rotate(o, d ^ 1);
        }
        o->Maintain();
    }
    
    void Remove(Node *&o, int x){
        int d = o->cmp(x);
    
        if (d == -1){
            Node *u = o;
    
            if (o->ch[0] != NULL && o->ch[1] != NULL){
                int d2 = (o->ch[0]->key > o->ch[1]->key ? 1 : 0);
    
                Rotate(o, d2);
                Remove(o->ch[d2], x);
            }else{
                if (o->ch[0] == NULL)
                    o = o->ch[1];
                else
                    o = o->ch[0];
                delete u;
            }
        }else
            Remove(o->ch[d], x);
        if (o != NULL)
            o->Maintain( );
    }
    
    int Find(Node *o, int x){
        while (o != NULL){
            int d = o->cmp(x);
    
            if (d == -1) return 1;
            else o = o->ch[d];
        }
        return 0;
    }
    
    int FindKth(Node *o, int k){
        int l_size = (o->ch[0] == NULL ? 0 : o->ch[0]->size);
        if (k == l_size + 1)
            return o->value;
        else if (k <= l_size)
            return FindKth(o->ch[0], k);
        else
            return FindKth(o->ch[1], k - l_size - 1);
    }
    
    void MakeEmpty(Node *root){
        if (root == NULL)
            return;
        if (root->ch[0])
            MakeEmpty(root->ch[0]);
        if (root->ch[1])
            MakeEmpty(root->ch[1]);
        delete root;
    }
    
    int main(){
        int n, case_id = 0, value;
    
        srand(100);
        while (scanf("%d", &n) != EOF){
            Node *root = NULL;
            int head = 0, tail = 0, ans;
            char str[10];
    
            printf("Case #%d:
    ", ++case_id);
            for (int i = 0; i < n; ++i){
                scanf("%s", str);
                if (str[0] == 'i'){
                    scanf("%d", &value);
                    queue[tail++] = value;
                    Insert(root, value);
                }
                else if (str[0] == 'o')
                    Remove(root, queue[head++]);
                else{
                    ans = FindKth(root, (tail - head) / 2 + 1);
                    printf("%d
    ", ans);
                }
            }
            MakeEmpty(root);
        }
        return 0;
    }
  • 相关阅读:
    ZOJ 3949 Edge to the Root( 树形dp)
    CCF201812-3 CIDR合并
    CF700E E. Cool Slogans
    BZOJ4552: [Tjoi2016&Heoi2016]排序
    BZOJ3238: [Ahoi2013]差异
    BZOJ4566: [Haoi2016]找相同字符
    Codeforces Global Round 1 A~F
    (HDU)1555-- How many days? (多少天)
    (HDU)1491-- Octorber 21st (校庆)
    (HDU)1465-- 不容易系列之一
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4584287.html
Copyright © 2011-2022 走看看