Cod sursa(job #812008)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 13 noiembrie 2012 11:26:45
Problema Sortare prin comparare Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>

using namespace std;

int n, m;
struct Treap
{
    int key, priority, weight;
    Treap *left, *right;
    Treap() {}
    Treap(int key, int priority, Treap *left, Treap *right)
    {
        this->key=key;
        this->priority=priority;
        this->left=left;
        this->right=right;
        this->weight=0;
    }
} *rad, *nil;

void doWeight(Treap* &nod)
{
    if(nod==nil)
        return;
    nod->weight=nod->left->weight+nod->right->weight+1;
}

void rotright(Treap* &nod)
{
    Treap *aux = nod->left;
    nod->left = aux->right;
    aux->right = nod;
    nod=aux;
    doWeight(nod->left);
    doWeight(nod->right);
    doWeight(nod);
}

void rotleft(Treap* &nod)
{
    Treap *aux = nod->right;
    nod->right = aux->left;
    aux->left = nod;
    nod=aux;
    doWeight(nod->left);
    doWeight(nod->right);
    doWeight(nod);
}

void balance(Treap* &nod)
{
    if(nod->priority < nod->left->priority)
        rotright(nod);
    else
    if(nod->priority < nod->right->priority)
        rotleft(nod);
}

void insert(Treap* &nod, int key, int priority)
{
    if(nod==nil)
    {
        nod=new Treap(key, priority, nil, nil);
        doWeight(nod);
        return;
    }

    if(key < nod->key)
        insert(nod->left, key, priority);
    else
        insert(nod->right, key, priority);

    balance(nod);
    doWeight(nod);
}

void erase(Treap* &nod, int key)
{
    if(nod==nil)
        return;

    if(key < nod->key)
        erase(nod->left, key);
    else
    if(key > nod->key)
        erase(nod->left, key);
    else
    {
        if(nod->left==nil && nod->right==nil)
        {
            delete nod;
            nod = nil;
        }

        if(nod->left->priority > nod->right->priority)
            rotright(nod);
        else
            rotleft(nod);
        erase(nod, key);
    }
}

int findK(Treap* &nod, int k)
{
    if(nod==nil)
        return 0;
    if(nod->left->weight + 1 == k)
        return nod->key;
    if(k <= nod->left->weight)
        return findK(nod->left, k);
    return findK(nod->right, k - (nod->left->weight) - 1);
}

void df(Treap* &nod)
{
    if(nod==nil)
        return;
    df(nod->left);
    printf("%d %d %d\n", nod->key, nod->priority, nod->weight);
    df(nod->right);
}

int main()
{
    freopen("algsort.in", "r", stdin);
    freopen("algsort.out", "w", stdout);

    srand(time(0));

    scanf("%d", &n);
    rad = nil = new Treap(0, 0, NULL, NULL);

    for(int i=1; i<=n; ++i)
    {
        int x;
        scanf("%d", &x);
        insert(rad, x, rand()%1000000000+1);
    }

    for(int i=1; i<=n; ++i)
        printf("%d ", findK(rad, i));
    printf("\n");

    return 0;
}