Abrakadabra
Абракадабра
Statement
A data-compression algorithm ("block-sort" compression) applies the
following transform to a block of data. A string P is a rotation of a
string S if it is obtained by a cyclic shift of S's characters: if
S = a1 a2 ... aN, then P = ap ap+1 ... aN a1 ... ap-1 for some
1 ≤ p ≤ N. Build an N×N table M whose rows are all N rotations of S,
sorted in lexicographic order. Let L be the last column of M.
The forward transform takes S and produces L together with K, the
row number of M that contains S itself (if S appears more than once
among the rotations, any one occurrence's row number is acceptable). This is
exactly the Burrows–Wheeler transform. Program ABRAKA must perform the
inverse transform: given L and K, recover the original string S.
Input / Output
The first line of ABRAKA.DAT contains two integers K and N
(1 ≤ N ≤ 30000, 1 ≤ K ≤ N). The second line contains the N characters
of L — lowercase Latin letters.
The single line of ABRAKA.SOL must contain the string S.
Constraints
- 1 ≤ N ≤ 30000
- 1 ≤ K ≤ N
Lconsists only of lowercase Latin letters
Example
Input (ABRAKA.DAT):
2 6
karaab
Output (ABRAKA.SOL):
abraka
For S = "abraka", the sorted rotation table M has S itself on row 2,
and its last column reads L = "karaab" — so decoding (K=2, L="karaab")
must recover "abraka".
Solution idea
This is the standard Burrows–Wheeler inverse. Stably sort the characters of
L (the last column) to get the first column F of M; because the
rotation table's rows are sorted lexicographically, the character following
each row's first column entry, read around the cycle, is exactly what L
records, which gives an LF-mapping: the occurrence of a character at
position i in L corresponds to the same occurrence of that character at
its sorted position in F. Building this correspondence with a counting
sort over the 26-letter alphabet takes O(N) time; walking it starting from
row K for N steps, prepending one character per step, reconstructs S.