Pagini recente » Cod sursa (job #846936) | Diferente pentru implica-te/arhiva-educationala intre reviziile 50 si 51 | Cod sursa (job #1307103) | Cod sursa (job #929433) | Cod sursa (job #940913)
Cod sursa(job #940913)
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <iostream>
#define pb push_back
using namespace std;
struct entry
{
string nr;
entry *left, *right;
int total, depth;
entry()
{
left = right = NULL;
total = 0;
depth = 0;
}
};
entry *root = new entry();
int n, k, limit, nrs;
string curr;
vector <string> list;
inline int comp(string s1, string s2)
{
if (s1.size() < s2.size())
return 1;
if (s1.size() > s2.size())
return 0;
return s1 < s2;
}
void add(entry *node)
{
if (node -> total == 0)
{
node -> nr = curr;
node -> total = 1;
node -> depth = 1;
nrs++;
return ;
}
if ((node -> nr).compare(curr) == 0)
return ;
if (!comp(node -> nr, curr))
{
if (node -> left == NULL)
node -> left = new entry();
add(node -> left);
}
else
{
if (node -> right == NULL)
node -> right = new entry();
add(node -> right);
}
int sons = 1, maxDepth = 0;
if (node -> left != NULL)
{
sons += node -> left -> total;
maxDepth = max(maxDepth, node -> left -> depth);
}
if (node -> right != NULL)
{
sons += node -> right -> total;
maxDepth = max(maxDepth, node -> right -> depth);
}
node -> total = sons;
node -> depth = maxDepth + 1;
}
string search(entry *node)
{
if (node -> left != NULL)
{
if (node -> left -> total >= k)
return search(node -> left);
k -= node -> left -> total;
}
if (k == 1)
return node -> nr;
k--;
return search(node -> right);
}
void getNodes(entry *node)
{
if (node -> left != NULL)
getNodes(node -> left);
list.pb(node -> nr);
if (node -> right != NULL)
getNodes(node -> right);
delete node;
}
void remake(int left, int right, entry *node)
{
int mid = (left + right) >> 1;
node -> nr = list[mid - 1];
node -> depth = 1;
node -> total = 1;
if (mid > left)
{
node -> left = new entry();
remake(left, mid - 1, node -> left);
}
if (mid < right)
{
node -> right = new entry();
remake(mid + 1, right, node -> right);
}
int sons = 1, maxDepth = 0;
if (node -> left != NULL)
{
sons += node -> left -> total;
maxDepth = max(maxDepth, node -> left -> depth);
}
if (node -> right != NULL)
{
sons += node -> right -> total;
maxDepth = max(maxDepth, node -> right -> depth);
}
node -> total = sons;
node -> depth = maxDepth + 1;
}
int main()
{
freopen("nums.in", "r", stdin);
freopen("nums.out", "w", stdout);
cin >> n;
int i, tip;
for (i = 1; i <= n; i++)
{
cin >> tip;
limit = max((int)sqrt(nrs) * 2, 20);
if (tip == 1)
{
cin >> curr;
add(root);
if (root -> depth > limit)
{
list.clear();
getNodes(root);
root = new entry();
remake(1, list.size(), root);
}
}
else
{
cin >> k;
cout << search(root) << '\n';
}
}
return 0;
}