Pagini recente » Cod sursa (job #399113) | Cod sursa (job #237000) | Cod sursa (job #1452903) | Cod sursa (job #1023889) | Cod sursa (job #2113355)
#include <fstream>
#include <vector>
#include <queue>
#include <string>
using namespace std;
ofstream fout ("nums.out");
class InputReader {
public:
InputReader() {}
InputReader(const char *name) {
fin = fopen(name, "r");
buffpos = Size - 1;
}
InputReader &operator >>(int &n) {
char ch = nextpos();
while(ch < '0' || ch > '9') {
ch = nextpos();
}
n = 0;
while('0' <= ch && ch <= '9') {
n = n * 10 + ch - '0';
ch = nextpos();
}
return *this;
}
InputReader &operator >> (string &s) {
char ch = nextpos();
while(ch < '0' || ch > '9') {
ch = nextpos();
}
while('0' <= ch && ch <= '9') {
s += ch;
ch = nextpos();
}
return *this;
}
private:
FILE *fin;
static const int Size = 1 << 17;
int buffpos;
char buff[Size];
inline char nextpos() {
++ buffpos;
if(buffpos == Size) {
buffpos = 0;
fread(buff, Size, 1, fin);
}
return buff[ buffpos ];
}
} fin ("nums.in");
typedef unsigned long long u64;
const int nmax = 1e5;
const int cif = 1;
const int base = 10;
int n;
vector< string > v;
vector< int > ord, lg[nmax + 1];
queue< int > q[ 2 ][ base ];
pair<int, int> op[nmax + 1];
int val[nmax + 1];
int aint[4 * nmax + 1];
inline int get (int i, int j) {
if ((int)v[ i ].size() <= j)
return 0;
return v[ i ][ j ] - '0';
}
void radix () {
for (int i = 1; i <= n; ++ i) {
if (op[ i ].first == 1) {
int x = op[ i ].second;
lg[(int)v[ x ].size()].push_back( x );
}
}
for (int j = 1; j <= nmax; ++ j) {
if (lg[ j ].size() == 0)
continue;
for (auto i : lg[ j ]) {
q[ 0 ][get(i, j - 1)].push( i );
}
int ind = 0;
for (int i = j - 2; i >= 0; i -= cif, ind = 1 - ind) {
for (int p = 0; p < base; ++ p) {
while (!q[ ind ][ p ].empty()) {
int x = q[ ind ][ p ].front();
q[ ind ][ p ].pop();
q[1 - ind][get(x, i)].push( x );
}
}
}
for (int p = 0; p < base; ++ p) {
while (!q[ ind ][ p ].empty()) {
int x = q[ ind ][ p ].front();
q[ ind ][ p ].pop();
ord.push_back( x );
}
}
}
}
bool egal (const string &a, const string &b) {
if (a.size() != b.size())
return 0;
for (int i = 0; i < (int)a.size(); ++ i)
if (a[ i ] != b[ i ])
return 0;
return 1;
}
void precalc () {
radix ();
for (int i = 0; i < (int)ord.size(); ) {
int j = i;
while (j < (int)ord.size() && egal(v[ ord[ i ] ], v[ ord[ j ] ])) {
val[ ord[ j ] ] = i + 1;
++ j;
}
i = j;
}
}
void update (int nod, int x, int y, int pos) {
if (x == y) {
aint[ nod ] = 1;
return ;
}
int mij = (x + y) / 2;
if (pos <= mij)
update(2 * nod, x, mij, pos);
else
update(2 * nod + 1, mij + 1, y, pos);
aint[ nod ] = aint[2 * nod] + aint[2 * nod + 1];
}
int query (int nod, int x, int y, int k) {
if (x == y)
return x;
int mij = (x + y) / 2;
if (k <= aint[2 * nod]) {
return query(2 * nod, x, mij, k);
} else {
return query(2 * nod + 1, mij + 1, y, k - aint[2 * nod]);
}
}
int main () {
fin >> n;
for (int i = 1; i <= n; ++ i) {
fin >> op[ i ].first;
if (op[ i ].first == 0) {
fin >> op[ i ].second;
} else {
string x;
fin >> x;
v.push_back( x );
op[ i ].second = (int)v.size() - 1;
}
}
precalc ();
for (int i = 1; i <= n; ++ i) {
if (op[ i ].first == 0) {
fout << v[ ord[query(1, 1, n, op[ i ].second) - 1] ] << "\n";
} else {
update(1, 1, n, val[ op[ i ].second ]);
}
}
fout.close();
return 0;
}