Cod sursa(job #2479904)

Utilizator radustn92Radu Stancu radustn92 Data 24 octombrie 2019 17:46:52
Problema Hashuri Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.47 kb
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;

struct item {
    int key, priority;

    item* left;
    item* right;

    item(int _key) {
        key = _key;
        priority = rand();
        left = right = NULL;
    }
};
typedef item* pitem;

// L, R: all in R > key
pair<pitem, pitem> split(pitem node, int key) {
    if (node == NULL) {
        return pair<pitem, pitem>(NULL, NULL);
    }

    if (key < node -> key) {
        pair<pitem, pitem> splitLeftChild = split(node -> left, key);
        node -> left = splitLeftChild.second;
        return pair<pitem, pitem>(splitLeftChild.first, node);
    }

    pair<pitem, pitem> splitRightChild = split(node -> right, key);
    node -> right = splitRightChild.first;
    return pair<pitem, pitem>(node, splitRightChild.second);
}

pitem insert(pitem node, pitem nodeToInsert) {
    if (node == NULL) {
        return nodeToInsert;
    }

    if (node -> priority < nodeToInsert -> priority) {
        pair<pitem, pitem> splitCurrentNode = split(node, nodeToInsert -> key);
        nodeToInsert -> left = splitCurrentNode.first;
        nodeToInsert -> right = splitCurrentNode.second;
        return nodeToInsert;
    } else if (nodeToInsert -> key < node -> key) {
        node -> left = insert(node -> left, nodeToInsert);
    } else {
        node -> right = insert(node -> right, nodeToInsert);
    }
    
    return node;
}

pitem merge(pitem node1, pitem node2) {
    if (node1 == NULL || node2 == NULL) {
        return node1 == NULL ? node2 : node1;
    }

    if (node1 -> priority > node2 -> priority) {
        node1 -> right = merge(node1 -> right, node2);
        return node1;
    }

    node2 -> left = merge(node1, node2 -> left);
    return node2;
}

pitem erase(pitem node, int key) {
    if (node == NULL) {
        return NULL;
    }

    if (key == node -> key) {
        return merge(node -> left, node -> right);
    } else if (key < node -> key) {
        node -> left = erase(node -> left, key);
    } else if (key > node -> key) {
        node -> right = erase(node -> right, key);
    }

    return node;
}

pitem find(pitem node, int key) {
    if (node == NULL) {
        return NULL;
    }

    if (node -> key == key) {
        return node;
    } else if (key < node -> key) {
        return find(node -> left, key);
    }

    return find(node -> right, key);
}

void debug(pitem node) {
    if (node == NULL) {
        return;
    }

    debug(node -> left);
    printf("%d ", node -> key);
    debug(node -> right);
}

void debugPrintln(pitem node) {
    debug(node);
    printf("\n");
}

int main() {
    freopen("hashuri.in", "r", stdin);
    freopen("hashuri.out", "w", stdout);
    srand(time(0));

    int operations, opType, no;
    pitem root = NULL;
    scanf("%d", &operations);
    for (int opNo = 0; opNo < operations; opNo++) {
        scanf("%d%d", &opType, &no);
        // printf("OP %d: %d %d\n", opNo, opType, no);
        switch(opType) {
            case 1: {
                pitem posInTreap = find(root, no);
                if (posInTreap == NULL) {
                    root = insert(root, new item(no));
                }
                break;
            }
            case 2: {
                root = erase(root, no);
                break;
            }
            case 3: {
                pitem posInTreap = find(root, no);
                printf("%d\n", (posInTreap == NULL) ? 0 : 1);
                break;
            }
        }

        // debugPrintln(root);
    }
    return 0;
}