Cod sursa(job #1752241)

Utilizator stefanzzzStefan Popa stefanzzz Data 3 septembrie 2016 12:13:24
Problema Order Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <ctime>
using namespace std;

int n;

struct Treap {
    int key, pr, sz;
    Treap *left, *right;

    Treap(int key, int pr, int sz, Treap *left, Treap *right): key(key), pr(pr), sz(sz), left(left), right(right) {}
};

Treap *root, *nil;

void treapInit() {
    srand(time(0));

    root = nil = new Treap(0, 0, 0, nullptr, nullptr);
}

void rotateLeft(Treap* &node) {
    Treap *t = node -> left;
    node -> left = t -> right;
    t -> right = node;
    node -> sz = (node -> left -> sz) + 1 + (node -> right -> sz);
    t -> sz = (t -> left -> sz) + 1 + (t -> right -> sz);
    node = t;
}

void rotateRight(Treap* &node) {
    Treap *t = node -> right;
    node -> right = t -> left;
    t -> left = node;
    node -> sz = (node -> left -> sz) + 1 + (node -> right -> sz);
    t -> sz = (t -> left -> sz) + 1 + (t -> right -> sz);
    node = t;
}

void balance(Treap* &node) {
    if((node -> left -> pr) > (node -> pr))
        rotateLeft(node);
    else if((node -> right -> pr) > (node -> pr))
        rotateRight(node);
}

void treapInsert(Treap* &node, int key, int pr) {
    if(node == nil) {
        node = new Treap(key, pr, 1, nil, nil);
        return;
    }
    if(key < node -> key) treapInsert(node -> left, key, pr);
    else treapInsert(node -> right, key, pr);

    balance(node);
}

int treapGetNthKey(Treap* &node, int n) {
    int leftSz = (node -> left -> sz);
    if(n <= leftSz) return treapGetNthKey(node -> left, n);

    n -= leftSz;
    if(n == 1) return node -> key;

    return treapGetNthKey(node -> right, n - 1);
}

void treapRemove(Treap* &node, int key) {
    assert(node != nil);

    if(key < node -> key) treapRemove(node -> left, key);
    else if(key > node -> key) treapRemove(node -> right, key);
    else {
        if(node -> left == nil && node -> right == nil) {
            delete node; node = nil;
            return;
        }
        ((node -> left -> pr) > (node -> right -> pr)) ? rotateLeft(node) : rotateRight(node);
        return treapRemove(node, key);
    }
    --(node -> sz);
}

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

    scanf("%d", &n);

    treapInit();
    for(int i = 1; i <= n; ++i)
        treapInsert(root, i, rand() + 1);

    int pos = 2, treapSize = n;
    for(int i = 0; i < n; ++i, --treapSize) {
        pos += i;
        while(pos > treapSize) pos -= treapSize;

        int x = treapGetNthKey(root, pos);
        printf("%d ", x);

        treapRemove(root, x);
    }

    printf("\n");

    return 0;
}