Cod sursa(job #444383)

Utilizator prisonbreakMichael Scofield prisonbreak Data 20 aprilie 2010 11:28:25
Problema Nums Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.7 kb
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
using namespace std;

#define MAXN 100100
#define MAXARB (1<<18)
#define pb push_back
#define left (nod << 1)
#define right ((nod << 1) | 1)
#define mid ((st+dr) >> 1)
#define mp make_pair

bool cmp(pair<string, int> a, pair<string, int> b)
{
	if(a.first.size() < b.first.size()) return true;
	if(a.first.size() > b.first.size()) return false;
	return a.first < b.first;
}

int M, N, Index[MAXN], oper[MAXN][2], arb[MAXARB];
vector< pair<string, int> > A;

void update(int nod, int st, int dr, int k)
{
	arb[nod]++;
	if(st == dr) return ;
	if(k <= mid) update(left, st, mid, k);
	if(k > mid) update(right, mid+1, dr, k);
}

int query(int nod, int st, int dr, int k)
{
	if(st == dr)
		return st;
	if(arb[left] >= k) return query(left, st, mid, k);
	return query(right, mid+1, dr, k-arb[left]);
}

void read_and_solve(void)
{
	int i, j, k, ins, tip;
	string s;
	scanf("%d\n", &M);
	for(i = 1; i <= M; i++)
	{
		scanf("%d ", &tip);
		if(tip == 1) // insert
		{
			cin >> s;
			A.pb( mp(s, N++) );
			oper[i][0] = 1;
		}
		else // query
		{
			scanf("%d\n", &k);
			oper[i][1] = k;
		}
	}
	sort(A.begin(), A.end(), cmp);
	for(i = 0; i < A.size(); i++)
		Index[A[i].second] = i;

	for(ins = 0, i = 1; i <= M; i++)
	 if(oper[i][0] == 1) // inserez sir
	 {
		 int x = Index[ins++];
		 update(1, 0, N-1, x);
	 }
	 else
	 {
		 k = oper[i][1];
		 int q = query(1, 0, N-1, k);
		 cout << A[q].first << '\n';
	 }
}

int main(void)
{
	freopen("nums.in", "rt", stdin);
	freopen("nums.out", "wt", stdout);

	read_and_solve();

	return 0;
}