Cod sursa(job #1715343)

Utilizator cercVianuCerc Vianu cercVianu Data 10 iunie 2016 13:24:11
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.53 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using std::pair;
using std::make_pair;

const int PLUS_INF = 0x7fffffff;
//    7    f    f    f    f    f    f    f
// 0111 1111 1111 1111 1111 1111 1111 1111
// 1000 0000 0000 0000 0000 0000 0000 0000
//    8    0    0    0    0    0    0    0
const int MINUS_INF = 0x80000000;

int cmmdc(int a, int b) {
  if (b == 0) {
    return a;
  } else {
    return cmmdc(b, a % b);
  }
}

int cmmmc(int a, int b) {
  return a * b / cmmdc(a, b);
}

int cmmmc(int a, int b, int c) {
  return cmmmc(a, cmmmc(b, c));
}

struct Node {
  int value;
  int priority; // Min Heap
  int size;
  int sum;
  int cmmmc;
  Node* left;
  Node* right;
};

Node* emptyNode = new Node{0, PLUS_INF, 0, 0, 1, nullptr, nullptr};

Node* makeLeaf(int value, int priority) {
  return new Node{
    value,
    priority,
    1,
    value,
    value,
    emptyNode,
    emptyNode};
}

Node* makeNode(Node* root, Node* left, Node* right) {
  //*root = Node{ // non-persistence
  root = new Node{ // persistence
    root->value,
    root->priority,
    left->size + 1 + right->size,
    left->sum + root->value + right->sum,
    cmmmc(left->cmmmc, right->cmmmc, root->value),
    left,
    right};
  return root;
}

Node* join(Node* first, Node* second) {
  if (first == emptyNode)
    return second;
  else if (second == emptyNode)
    return first;
  else if (first->priority < second->priority) {
    return makeNode(first,
        first->left,
        join(first->right, second));
  } else {
    return makeNode(second,
        join(first, second->left),
        second->right);
  }
}

pair<Node*, Node*> split(Node* root, int value) {
  if (root == emptyNode) {
    return make_pair(emptyNode, emptyNode);
  } else if (value <= root->value) {
    pair<Node*, Node*> tmp = split(root->left, value);
    return make_pair(
       tmp.first,
       makeNode(root, tmp.second, root->right)
    );
  } else {
    pair<Node*, Node*> tmp = split(root->right, value);
    return make_pair(
       makeNode(root, root->left, tmp.first),
       tmp.second
    );
  }
}

bool find(Node* root, int value) {
  if (root == emptyNode)
    return false;
  else if (root->value == value)
    return true;
  else if (value < root->value)
    return find(root->left, value);
  else
    return find(root->right, value);
}

Node* insert(Node* root, Node* node) {
  if (node->priority < root->priority) {
    pair<Node*, Node*> tmp = split(root, node->value);
    return makeNode(node, tmp.first, tmp.second);
  } else if (node->value < root->value) {
    return makeNode(
        root,
        insert(root->left, node),
        root->right);
  } else { // if (root->value < node->value)
    return makeNode(
        root,
        root->left,
        insert(root->right, node));
  }
}

Node* insert(Node* root, int value) {
  if (!find(root, value)) {
    int priority = rand();
    return insert(root, makeLeaf(value, priority));
  } else {
    return root;
  }
}

Node* erase(Node* root, int value) {
  if (root == emptyNode)
    return root;
  else if (root->value == value)
    return join(root->left, root->right);
  else if (value < root->value)
    return makeNode(root,
        erase(root->left, value),
        root->right);
  else
    return makeNode(root,
        root->left,
        erase(root->right, value));
}

void printSpaces(int size) {
  if (size > 0) {
    printf(" ");
    printSpaces(size - 1);
  }
}

void dump(Node* root, int depth = 0) {
  if (root != emptyNode) {
    dump(root->left, depth + 1);
    printSpaces(depth);
    printf("%2d\t%10d\t%2d\t%2d\n",
        root->value,
        root->priority,
        root->size,
        root->sum);
    dump(root->right, depth + 1);
  }
}

Node* queryInterval(Node* root, int left, int right) {
  pair<Node*, Node*> tmp = split(root, left);
  tmp = split(tmp.second, right + 1);
  return tmp.first;
}

int main(void) {
  srand(time(NULL));
  Node* root1 = emptyNode;
  Node* root2 = insert(root1, 5);
  Node* root3 = insert(root2, 3);
  Node* root4 = insert(root3, 7);
  Node* root5 = insert(root4, 4);
  Node* root6 = insert(root5, 9);
  Node* root7 = insert(root6, 2);
  Node* root8 = insert(root7, 1);
  Node* root9 = insert(root8, 6);
  Node* root10 = erase(root9, 4);
  dump(root1);
  printf("\n");
  dump(root2);
  printf("\n");
  dump(root3);
  printf("\n");
  dump(root4);
  printf("\n");
  dump(root5);
  printf("\n");
  dump(root6);
  printf("\n");
  dump(root7);
  printf("\n");
  dump(root8);
  printf("\n");
  dump(root9);
  printf("\n");
  dump(root10);
  printf("\n");
  printf("%d\n", queryInterval(root10, 5, 7)->cmmmc);
  return 0;
}