poj 1442 Black Box(优先队列&Treap)

题目链接:http://poj.org/problem?id=1442

思路分析:

<1>维护一个最小堆与最大堆,最大堆中存储最小的K个数,其余存储在最小堆中;

<2>使用Treap构造名次树,查询第K大数即可;

 

代码如下(堆的用法):

#include<iostream>
#include<queue>
using namespace std;

struct cmp1
{
     bool operator() ( const int a, const int b )
     { return a > b; }
};

struct cmp2
{
     bool operator()( const int a, const int b )
     { return a < b; }
};

priority_queue<int,vector<int>,cmp1>MaxHeap;
priority_queue<int,vector<int>,cmp2>MinHeap;
int a[30000];

int main()
{
    int m, n, i, K;
    int Count = 0, Tmp;
    
    scanf( "%d%d", &m, &n );
    for ( i = 0; i < m; i++ )
        scanf( "%d", &a[i] );
    
    for( i = 0; i < n; i++ )
    {
        scanf( "%d", &K );
        while ( Count < K )
        {
            MaxHeap.push(a[Count]);
            if( !MinHeap.empty() && MaxHeap.top() < MinHeap.top() )
            {
                Tmp = MaxHeap.top();
                MaxHeap.pop();
                MaxHeap.push( MinHeap.top() );
                MinHeap.pop();
                MinHeap.push(Tmp);
            }
            Count++;
        }
        printf( "%d\n", MaxHeap.top() );
        MinHeap.push( MaxHeap.top() );
        MaxHeap.pop();
    }
}

 

代码如下(Treap):

#include <cstdio>
#include <ctime>
#include <cstring>
#include <iostream>
using namespace std;

const int MAX_N = 300000 + 100;
int add[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){
        if (o->ch[0] == NULL)
            o = o->ch[1];
        else if (o->ch[1] == NULL)
            o = o->ch[0];
        else{
            int d2 = (o->ch[0]->key > o->ch[1]->key ? 1 : 0);
            Rotate(o, d2);
            Remove(o->ch[d2], x);
        }
    }
    else
        Remove(o->ch[d], x);
}

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);
}

int main()
{
    int m, n, k;
    Node *root = NULL;

    srand(100);
    scanf("%d %d", &m, &n);
    for (int i = 1; i <= m; ++i)
        scanf("%d", &add[i]);
    int j = 1;
    for (int i = 1; i <= n; ++ i){
        scanf("%d", &k);

        for (; j <= k; ++j)
            Insert(root, add[j]);
        printf("%d\n", FindKth(root, i));
    }
    return 0;
}

 

你可能感兴趣的:(优先队列)