Pagini recente » Cod sursa (job #2234218) | Cod sursa (job #2382505) | Cod sursa (job #353251) | Cod sursa (job #3121090) | Cod sursa (job #2562497)
#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;
}