Cod sursa(job #2562497)

Utilizator radustn92Radu Stancu radustn92 Data 29 februarie 2020 15:01:57
Problema Nums Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.96 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;



struct stringWrapper {
	vector<int> numbers;
	int size;

	stringWrapper() {}

	int getNumberBetween(string& s, int startIdx, int endIdx) {
		int result = 0;
		for (int idx = startIdx; idx <= endIdx; idx++) {
			result = result * 10 + s[idx] - '0';
		}
		return result;
	}

	stringWrapper(string& s) {
		size = s.size();
		numbers.reserve(size % 9 == 0 ? size / 9 : size / 9 + 1);
		for (int i = 0; i < s.size() / 9; i++) {
			numbers.push_back(getNumberBetween(s, i * 9, (i + 1) * 9 - 1));
		}
		if (s.size() % 9 != 0) {
			numbers.push_back(getNumberBetween(s, s.size() / 9 * 9, s.size() - 1));
		}
	}

	bool operator < (const stringWrapper& other) const {
		if (size < other.size) {
			return true;
		} else if (size > other.size) {
			return false;
		}

		for (int idx = 0; idx < numbers.size(); idx++) {
			if (numbers[idx] < other.numbers[idx]) {
				return true;
			} else if (numbers[idx] > other.numbers[idx]) {
				return false;
			}
		}
		return false;
	}

	bool operator == (const stringWrapper& other) const {
		if (size != other.size) {
			return false;
		}
		return numbers == other.numbers;
	}

	void printNumber(int number, int digitsNo) {
		vector<int> result;
		for (int cnt = 0; cnt < digitsNo; cnt++) {
			result.push_back(number % 10);
			number /= 10;
		}
		reverse(result.begin(), result.end());
		for (auto& digit : result) {
			cout << digit;
		}
	}

	void printUnderlyingString() {
		for (int idx = 0; idx < numbers.size(); idx++) {
			if (idx < numbers.size() - 1) {
				printNumber(numbers[idx], 9);
			} else {
				printNumber(numbers[idx], size - size / 9 * 9);
			}
		}
	}
};

struct node {
	stringWrapper key;
	int priority;
	int size;

	node* leftChild;
	node* rightChild;

	node() {}

	node(stringWrapper _key) {
		key = _key;
		priority = rand();
		leftChild = rightChild = NULL;
	}
};
typedef node* pnode;

int getSize(pnode node) {
	if (node == NULL) {
		return 0;
	}
	return 1 + getSize(node -> leftChild) + getSize(node -> rightChild);
}

void updateSize(pnode node) {
	if (node != NULL) {
		node -> size = getSize(node);
	}
}

pair<pnode, pnode> split(pnode root, stringWrapper& key) {
	if (root == NULL) {
		return {NULL, NULL};
	}
	if (key < root -> key) {
		pair<pnode, pnode> leftSplit = split(root -> leftChild, key);
		root -> leftChild = leftSplit.second;
		updateSize(root);
		return {leftSplit.first, root};
	}
	pair<pnode, pnode> rightSplit = split(root -> rightChild, key);
	root -> rightChild = rightSplit.first;
	updateSize(root);
	return {root, rightSplit.second};
}

pnode merge(pnode leftTree, pnode rightTree) {
	if (leftTree == NULL || rightTree == NULL) {
		return (leftTree == NULL) ? rightTree : leftTree;
	}

	if (leftTree -> priority > rightTree -> priority) {
		leftTree -> rightChild = merge(leftTree -> rightChild, rightTree);
		updateSize(leftTree);
		return leftTree;
	}
	rightTree -> leftChild = merge(leftTree, rightTree -> leftChild);
	updateSize(rightTree);
	return rightTree;
}

pnode search(pnode root, stringWrapper& key) {
	if (root == NULL || root -> key == key) {
		return root;
	}
	if (key < root -> key) {
		return search(root -> leftChild, key);
	}
	return search(root -> rightChild, key);
}

pnode insert(pnode root, pnode toInsert) {
	if (root == NULL) {
		return toInsert;
	}
	if (toInsert -> priority > root -> priority) {
		pair<pnode, pnode> splitByInsertionKey = split(root, toInsert -> key);
		toInsert -> leftChild = splitByInsertionKey.first;
		toInsert -> rightChild = splitByInsertionKey.second;
		updateSize(toInsert);
		return toInsert;
	}
	if (toInsert -> key < root -> key) {
		root -> leftChild = insert(root -> leftChild, toInsert);
	} else {
		root -> rightChild = insert(root -> rightChild, toInsert);
	}
	updateSize(root);
	return root;
}

pnode insert(pnode root, stringWrapper& key) {
	pnode prevNode = search(root, key);
	if (prevNode == NULL) {
		root = insert(root, new node(key));
	}
	return root;
}

pnode findKth(pnode root, int K) {
	if (root == NULL) {
		return NULL;
	}

	int currNodeIdx = getSize(root -> leftChild) + 1;
	if (K == currNodeIdx) {
		return root;
	} else if (K < currNodeIdx) {
		return findKth(root -> leftChild, K);
	}
	return findKth(root -> rightChild, K - currNodeIdx);
}

void debug(pnode root) {
	if (root == NULL) {
		return;
	}
	debug(root -> leftChild);
	(root -> key).printUnderlyingString();
	cout << " ";
	debug(root -> rightChild);
}

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

	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	pnode root = NULL;
	int totalOps, opType, K;
	cin >> totalOps;
	for (int opIdx = 0; opIdx < totalOps; opIdx++) {
		cin >> opType;
		if (opType == 1) {
			string newString;
			cin >> newString;
			stringWrapper wrapper(newString);
			root = insert(root, wrapper);
		} else {
			cin >> K;
			pnode kThElement = findKth(root, K);
			(kThElement -> key).printUnderlyingString();
			cout << "\n";
		}
	}
	return 0;
}