CSES - String Transform

Author: Benjamin Qi


GFG does an okay (?) job of explaining it and giving some intuition. But the code can be so much shorter ...

My Implementation

Let t[0n1]t[0\ldots n-1] be the BWT of s[0n1]s[0\ldots n-1], where ss ends with a character that is smaller than all other characters in ss (# in this case).

Consider all indices modulo nn. If tit_i corresponds to sxi1s_{x_i-1} (the last character of the ii-th smallest rotation) then define

ai=sxisxi+1sxi1a_i=s_{x_i}s_{x_i+1}\ldots s_{x_i-1}
bi=sxi1sxisxi+1sxi2b_i=s_{x_i-1}s_{x_i}s_{x_i+1}\ldots s_{x_i-2}

aia_i corresponds to the ii_th smallest rotation of ss, and bib_i is formed by cyclically shifting aia_i by one character. tit_i is the last character of aia_i and the first character of bib_i.

Define j=nex[i]j=\texttt{nex}[i] to be the unique jj such that bj=aib_j=a_i. Then we know that xj=xi+1x_{j}=x_i+1. Given nex\texttt{nex}, we can compute

x0=n1x_0=n-1
xnex1[0]=0x_{\texttt{nex}^1[0]}=0
xnex2[0]=1x_{\texttt{nex}^2[0]}=1
\vdots

so si=snexi+1[0]=tnexi+2[0]s_i=s_{\texttt{nex}^{i+1}[0]}=t_{\texttt{nex}^{i+2}[0]} for all ii.

We know that

bi<bj(ti,ai)<(tj,aj)(ti,i)<(tj,j),b_i<b_j\Longleftrightarrow (t_i,a_i)<(t_j,a_j) \Longleftrightarrow (t_i,i)<(t_j,j),

so we can sort the bib_i using a stable sort. Then nex[i]\texttt{nex}[i] is just the index of the ii-th rotation in this sort!

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using db = double;
using str = string; // yay python!
using pi = pair<int, int>;
using pl = pair<ll, ll>;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!