Algorithm
int[] kasai(String s, int[] sa) {
int n = s.length();
int[] rank = new int[n], lcp = new int[n];
for (int i = 0; i < n; i++) rank[sa[i]] = i;
int h = 0;
for (int i = 0; i < n; i++) {
if (rank[i] > 0) {
int j = sa[rank[i] - 1];
while (i + h < n && j + h < n && s.charAt(i + h) == s.charAt(j + h)) h++;
lcp[rank[i]] = h;
if (h > 0) h--;
} else h = 0;
}
return lcp;
}Advertisement
Why O(N)
h decreases by at most 1 per iteration. Total increments = O(N). Total decrements = O(N).
Advertisement
Applications
Longest repeated substring = max LCP. Distinct substrings via LCP sum. Range min queries on LCP → LCP between any two suffixes.
LCP RMQ
Preprocess LCP with sparse table → LCP(i,j) in O(1) via RMQ of LCP[min+1..max].